Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java heap - bigger than it needs to be

Tags:

java

memory

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?

like image 913
biffta Avatar asked May 10 '17 17:05

biffta


People also ask

How Big Should Java heap size be?

It is recommended to increase the Java heap space only up to one-half of the total RAM available on the server. Increasing the Java heap space beyond that value can cause performance problems. For example, if your server has 16 GB of RAM available, then the maximum heap space you should use is 8 GB.

What happens if you specify max heap size greater than available RAM?

If your -Xmx (maximum) is larger than the available memory (total memory to include any virtual memory) you will get a runtime failure if and only if your JVM processes actually tries to use more memory than the machine has. Whether or not the system starts to swap heavily depends on your OS settings.

Does increasing heap size improve performance?

The difference between the maximum address space and the total of those values is the amount of memory that can be allocated to the heap. You can improve performance by increasing your heap size or using a different garbage collector.


1 Answers

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

like image 156
Arthur Landim Avatar answered Sep 22 '22 07:09

Arthur Landim