Java 堆内存分配限制
Java heap memory allocation limits
我编写了以下测试来检查最大可用堆内存:
import java.util.*;
public class Memory {
public static void main(String[] args) {
long maxMB = Runtime.getRuntime().maxMemory() / 1048576L;
System.out.println("Maximum memory is " + maxMB + " MB.");
ArrayList<byte[]> allocated = new ArrayList<>();
try {
while (true)
allocated.add(new byte[1024*1024]);
} catch (OutOfMemoryError e) {
System.out.println("allocated " + allocated.size() + " MB before running out of memory.");
}
}
}
然而,当我对此进行测试时,似乎实际上只能分配一半的“可用”内存:
$ java -Xmx512m Memory
Maximum memory is 512 MB.
allocated 255 MB before running out of memory.
$ java -Xmx1024m Memory
Maximum memory is 1024 MB.
allocated 511 MB before running out of memory.
有人知道为什么会这样吗?
我相信发生的事情是内存管理器试图在下一个可用的 1MB 边界对齐块。但由于 1MB 的数组实际上占用略多于 1MB(用于存储长度和其他内容),因此它们之间的间隔几乎为 1MB。当将块大小减少 16 字节时,它们突然又用完了整个内存。
我编写了以下测试来检查最大可用堆内存:
import java.util.*;
public class Memory {
public static void main(String[] args) {
long maxMB = Runtime.getRuntime().maxMemory() / 1048576L;
System.out.println("Maximum memory is " + maxMB + " MB.");
ArrayList<byte[]> allocated = new ArrayList<>();
try {
while (true)
allocated.add(new byte[1024*1024]);
} catch (OutOfMemoryError e) {
System.out.println("allocated " + allocated.size() + " MB before running out of memory.");
}
}
}
然而,当我对此进行测试时,似乎实际上只能分配一半的“可用”内存:
$ java -Xmx512m Memory
Maximum memory is 512 MB.
allocated 255 MB before running out of memory.
$ java -Xmx1024m Memory
Maximum memory is 1024 MB.
allocated 511 MB before running out of memory.
有人知道为什么会这样吗?
我相信发生的事情是内存管理器试图在下一个可用的 1MB 边界对齐块。但由于 1MB 的数组实际上占用略多于 1MB(用于存储长度和其他内容),因此它们之间的间隔几乎为 1MB。当将块大小减少 16 字节时,它们突然又用完了整个内存。