Out of memory error: Java heap size when memory is available
java, memory
Solution
Analysis
The first thing you need to do is get a heap dump so you can figure out exactly what the heap looks like when the JVM crashes. Add this set of flags to the command line:
-XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails
When a crash happens, the JVM is going to write out the heap to disk. And frankly, its going to take a long time on a heap that size. Download Eclipse MAT or install the plugin if you're already running Eclipse. From there, you can load up the heap dump and run a couple of canned reports. You'll want to check the Leak Suspects and Dominator Tree to see where your memory is going and determine that you don't have an actual leak.
After that, I would recommend you read this document by Oracle about Garbage Collection, however here are some things you can consider:
Concurrent GC
-XX:+UseConcMarkSweepGC
I've never heard of anyone getting away with using the parallel only collector on a heap that size. You can activate the concurrent collector, and you'll want to read up on incremental mode and determine if its right for your workload / hardware combo.
Heap Free Ratio
-XX:MinHeapFreeRatio=25
Dial this down to lower the bar for the garbage collector when you do a full collection. This may prevent you from running out of memory doing a full collection. 40% is the default, experiment with smaller values.
New Ratio
-XX:NewRatio
We'll need to hear more about your actual workload: is this a webapp? A swing app? Depending on how long objects are expected to remain alive on the heap will have an impact on the new ratio value. Server-mode VMs like the one you're running have a fairly high new ratio by default (8:1), this may not be ideal for you if you have a lot of long-lived objects.
Problem
I'm running java with `java -Xmx240g mypackage.myClass` OS is Ubuntu 12.10. `top` says `MiB Mem 245743 total`, and shows that java process has `virt 254g` since the very beginning, and `res` is steadily increasing up to `169g`. At that point it looks like it starts garbage collect a lot, I think so because the program is single-threaded at that point, and `CPU%` is mostly `100%` up to this point, and it jumps around 1300-2000 at this point (I conclude it is multithreaded garbage collector), and then `res` slowly moves to `172g`. At that point java crashes with `Exception in thread "main" java.lang.OutOfMemoryError: Java heap space` at the line with `new double[2000][5]` `java -version` says `java version "1.7.0_15" OpenJDK Runtime Environment (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.10) OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)` Hardware is Amazon cr1.8xlarge instance It seems to me that java crashes even when there's a lot of memory available. It is clearly not possible, I have to interpret some numbers wrong. Where should I look to understand what's going on? Edit: I don't specify any GC options. The only command-line option is `-Xmx240g` My program is successfully working on many inputs, and `top` said sometimes that it uses up to 98.3% of memory. However I reproduced the situation described above with certain program input. Edit2: This is scientific application. It has gigantic tree (1-10 millions of nodes), in each node there are couple `double` arrays with size approx. 300x3 - 900x5. After initial tree creation program does not allocate much memory. Most of the time there are some arithmetic operations going on with these arrays. Edit3: HotSpot JVM died the same way, used CPU a lot at 170-172g mark and crashed with the same error. Looks like 70-75% of memory is some magical line that JVM does not want to cross. Final solution: With -XX:+UseConcMarkSweepGC -XX:NewRatio=12 program made it through 170g mark and is happily working further.