Analyze and fix full GC in Java

I am working on a critical time time with a time limit of 40 ms per iteration. If the time limit is exceeded only once, the application is terminated and the game ends. The application itself does not have problems staying under 40 ms, it is a garbage collector that sometimes exceeds the limit.

Using the object pool in combination with the factory pattern, I basically managed to eliminate the need for garbage collection, and the application achieved a stable iteration time of 17 ms, including small GC runs, except that from 10 to 20 iterations after the application was launched, there was only one complete GC that exceeds 40ms and kills my application.

My question is, how can I analyze what exactly causes this full GC? I used jvisualvm extensively to describe the runtime and amount of memory, and this helped identify the objects that I need to cache. But in this particular case, I can’t use it, because the full GC happens long before I can press the right buttons in jvisualvm. Is there a way to generate a bunch of heaps programmatically?

+4
source share
5 answers

I would use a commercial memory profiler such as YourKit. You can get a free eval license from most of them long enough to solve your problem .;)

The problem I found with VisualVM is that when you minimize your object creation, the largest memory producers are Memory Profiler itself. Commercial profilers do not have this problem because they use heap memory.

I would see what you can do to reduce your garbage further. 17 ms is still a long time, you can think about profiling the CPU. Profilers are useful for about half a second. For lower than this, you need to use the exact time of your own and some trial and error.

Something I found useful is to execute the processor profile and the memory profile, run them both at once, and you will get more suggestions as to what you can improve.

If you reduce the amount of garbage that you produce and increase the amount of space, you can get a small collection once a day.

http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

+3
source

You heard about HeapDumpOnCtrlBreak; Try this link

or alternatively using

jmap -dump:format=b,file=<filename.hprof> <pid> 
+1
source

Collecting garbage on the JVM is a huge advantage most of the time, but the main drawback (as you defined) is that it sometimes causes unpredictable GC pauses.

The standard JVM is fine for soft real-time (when you can tolerate a random pause), but not suitable for hard real-time (i.e. when any pause outside this tolerance causes an error / failure)

Some helpful tips:

  • Go to a dedicated real-time JVM if you can (e.g. Zing JVM ). This is the best way to reliably get real-time behavior with Java.
  • Use low latency libarries, for example. Javolution - this can help in many respects thanks to the provision of data structures with very low distribution rates of objects (and, consequently, lower costs for managing GC)
+1
source

You can try the trial version of jprofiler , this allows you to make the application wait until the profiler starts. This does not affect heap memory, and it is a powerful profiler in general, with good IDE integration and one-click configuration.

But since you say that you cannot control the heap size or the gc settings, you cannot do much. Loading classes at startup creates garbage that needs to be collected.

May I ask: is this homework or just some kind of competition / challenge?

+1
source

Have you tried to configure garbage collection options? If you are on a machine with sufficient RAM and more than one core, you should be able to use parallel garbage collection. It is enabled by default on Java 1.6 JVMs . Basically, if you ensure that the young generation is large enough so that the objects never advance to the old generation (which is assembled in sequential order).

0
source

All Articles