5

My maths says the following Java program would need approx 8GB (2147483645 * 4 bytes) of RAM:

package foo;

public class Foo {
    public static void main(String[] args) throws Exception {
        int[] arr = new int[Integer.MAX_VALUE-2];
        Thread.sleep(500000L);
    }
}

This is backed up by observing the program when running: jvisualvm memory pic

But unless you set the max heap to around 12.5GB, the program fails to start:

$ java -Xmx12000m -cp ./ foo.Foo
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at foo.Foo.main(Foo.java:5)
$ java -Xmx12500m -cp ./ foo.Foo
//this works

Can understand the need for a bit of wiggle-room but why do we need so much?

biffta
  • 189
  • 1
  • 6
  • 2
    Explain "your maths" – OneCricketeer May 10 '17 at 17:17
  • 2
    Certainly your code contains more than `int[] arr = new int[Integer.MAX_VALUE-2];`. Without telling us what that is, it is hard to determine the problem. – bradimus May 10 '17 at 17:18
  • Possibly related: http://stackoverflow.com/questions/8419860/integer-vs-int-with-regard-to-memory – OneCricketeer May 10 '17 at 17:21
  • 2
    What? This is a totally valid question about the arrangement of the Java heap, which does in fact require significantly more space than the largest object in it. – Louis Wasserman May 10 '17 at 17:25
  • JVM itself needs some free space to breathe. If you REALLY need to allocate so much memory, you could try to search for off-heap allocation (e.g. using ByteBuffer). – gusto2 May 10 '17 at 17:38
  • bradimus: provided the full program, nothing else going on. cricket_007: maths is basically just MAX_INT * 4btyes per int. gusto2: I understand it need **some** space to breathe but why isn't 4GB enough? – biffta May 10 '17 at 17:42

1 Answers1

5

Its because of the MinHeapFreeRatio default value (which is 40%). If you want to "need" less then you have to specify it: e.g. 5% -XX:MinHeapFreeRatio=5

Also, you need to change memory allocated to the young generation as it plays a important role in memory allocation:

After total available memory, the second most influential factor affecting garbage collection performance is the proportion of the heap dedicated to the young generation.

try this:

java -Xmx9g -XX:MinHeapFreeRatio=1 -XX:MaxNewSize=256m -cp ./ foo.Foo

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/sizing.html

Arthur Landim
  • 384
  • 2
  • 9