Reputation: 2657
I've written the following test to check maximum available heap memory:
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.");
}
}
}
However, when I test this, it appears that only half of the "available" memory can actually be allocated:
$ 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.
Anyone know why this would be the case?
Upvotes: 6
Views: 1001
Reputation: 2657
I believe what happens is that the memory manager tries to align the chunks at the next available 1MB boundary. But as the 1MB arrays actually take up slightly more than 1MB (for storing length and something else), they get arranged with a gap of almost 1MB between them. When reducing the block size by 16 bytes, they suddenly use up the whole memory again.
Upvotes: 2