I am using parallel GC in my java program. But when jvm have less then ~400mb of free memory GC starts to consume all of CPU. And after some time jvm crash with java.lang.OutOfMemoryError: GC overhead limit exceeded. But i am printing the amount of free memory with Runtime.getRuntime().freeMemory(), and i am sure that jvm have ~400mb of free space. I tried to set -XX:MinHeapFreeRatio to 1 or 5 but it made everything worst.

How to config GC or which one should i choose to prevent it from consumimg all of CPU and crashing jvm?My jvm flags is -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -Xmx3800m -server -Djava.library.path="native_libs"

  • How to config GC or which one should i choose to prevent it from consumimg all of CPU and crashing jvm? There is no such magic setting when you are using 90% of memory. Add more memory.– Elliott FrischFeb 14 at 20:19
  • But i need to store only ~50mb of data in the moment of crash. Why i cant say to GC that 400mb of memory it is ok? And after it i will free the huge amount of memory.– OlleggerrFeb 14 at 20:32
  • Because Java doesn't support explicit memory management. Saying it is ok does not make it okay, but the older (and slower) client version (using -client) might allow for lower memory conditions to work. There's no silver bullet here (but memory is cheap!)– Elliott FrischFeb 14 at 20:41
  • Memory is cheap, but i am poor xD. Thanks for answer. I'll try to optimize memory consumption.– OlleggerrFeb 14 at 21:00
  • If you only need 50mb then I wouldn't expect any GC issues with a max heap of 3800mb.. Something is wrong there, and its not the GC.– NickLFeb 14 at 23:44

The Error

The error java.lang.OutOfMemoryError: GC overhead limit exceeded occurs when the JVM spends most of it's time garbage collecting without being able to free much memory at the end of a garbage collection cycle. A good detailed description can be found here. Note this does not necessarily mean that you are out of memory! You may have a lot of memory left, but the garbage collector may just not be able to free anything and is giving up early.

The Cause

Since you are saying that you only need 50 mb memory at the time this exception happens, you are likely leaking memory. Using only 50 mb of memory would not cause the garbage collector to fail like this. Leaking memory happens when you still have references to objects that you no longer need. When too many objects are still accessible garbage takes a long time, and the garbage collector is not able free any Objects because they are still accessible to the program.

The Solution

You need to find the source of the memory leak. Common causes are keeping objects in data structures like Lists, Maps, and Sets without removing them. You can take a heap dump, which essentially saves all the Objects in your java program's memory to a file, which you can then inspect. You can configure java to do a heap dump when an OutOfMemoryException happens by adding the -XX:+HeapDumpOnOutOfMemoryError flag to your java command. More details about where the heap dump is stored can be found on this question Using HeapDumpOnOutOfMemoryError parameter for heap dump for JBoss. Then the next time things crash you can use a tool like Eclipse MAT to inspect the heap dump and see what objects are consuming memory. This will point you in the direction of your memory leak so that you can fix it.

  • Sorry i was incorrect. I need 50mb more of memory, before i could free huge amount of it. The total consumption in moment of jvm crash is ~3400mb. And i have ~400mb of free space.– OlleggerrFeb 15 at 10:42
  • Then you need to do some tuning. Increase the memory you have available first to something like 6gb to reduce the pressure on GC with this flag -Xmx6g. If that doesn't work read this article cubrid.org/blog/how-to-tune-java-garbage-collection. Main takeaway is you should try different GC algorithms. Also look at how much memory is consumed by Old objects with this commandjstat -gcutil <PID> <milliseconds between messages> <num messages> . If you are consuming a lot of Old space try tweaking the NewRatio (described in the article).– iloonerFeb 15 at 17:55
  • @Olleggerr where did you get the 50mb figure from, are you sure you don't need more? For example, parsing a 50mb xml file may require much more than 50mb memory.– NickLFeb 15 at 19:33
  • @ilooner Thanks. Yong generation tuning helped me. -XX:MaxNewSize– OlleggerrFeb 15 at 19:41
  • 1
    @NickL I was creating plain objects when crush happend. So i just calculate how many this objects i need to create and multiply it by the size of object. Size of object was calculated with jol.– OlleggerrFeb 15 at 19:46

My app have a lot stuff in old gen, so how i understood GC was trying to free enough memory for young gen and have been making full gc very often. So by reducing Young gen size i extend size of old gen, which was heavily used by me.

To reduce Young gen size you can use -XX:MaxNewSize, -XX:NewRatio, -XX:NewSize. I used -XX:MaxNewSize. You can read about it here https://docs.oracle.com/cd/E19900-01/819-4742/abeik/index.html

    Your Answer

     
    discard

    By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

    Not the answer you're looking for? Browse other questions tagged or ask your own question.