-1

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"

Olleggerr
  • 33
  • 1
  • 8
  • *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 Frisch Feb 14 '18 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. – Olleggerr Feb 14 '18 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 Frisch Feb 14 '18 at 20:41
  • Memory is cheap, but i am poor xD. Thanks for answer. I'll try to optimize memory consumption. – Olleggerr Feb 14 '18 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. – NickL Feb 14 '18 at 23:44
  • Please don't update your question with solution, post your own answer or accept an existing answer instead see [tour] to learn more – Petter Friberg Feb 15 '18 at 19:48

3 Answers3

3

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.

ilooner
  • 1,962
  • 10
  • 24
  • 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. – Olleggerr Feb 15 '18 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 https://www.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 command`jstat -gcutil ` . If you are consuming a lot of **Old** space try tweaking the **NewRatio** (described in the article). – ilooner Feb 15 '18 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. – NickL Feb 15 '18 at 19:33
  • @ilooner Thanks. Yong generation tuning helped me. `-XX:MaxNewSize` – Olleggerr Feb 15 '18 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. – Olleggerr Feb 15 '18 at 19:46
1

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

Olleggerr
  • 33
  • 1
  • 8
0

java.lang.OutOfMemoryError exception is one common indication of a memory leak.

Usually, this error is thrown when there is insufficient space to allocate an object in the Java heap. In this case, The garbage collector cannot make space available to accommodate a new object, and the heap cannot be expanded further.

Also, this error may be thrown when there is insufficient native memory to support the loading of a Java class.

In a rare instance, a java.lang.OutOfMemoryError may be thrown when an excessive amount of time is being spent doing garbage collection and little memory is being freed.

Details here

Nikaido
  • 3,671
  • 5
  • 29
  • 40