Java – Garbage collection: how is Eden space (and the other generation sizes) calculated

garbage-collectionjavasolr

I need help understanding how the GC-related numbers I'm getting from jmap and jstat relate to the settings I'm passing to java. I'm starting the app (solr) with the following settings on a sever with 16GB of memory:

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled 
-Xms12144m -Xmx12144m 
-XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops

The output of jmap begins:

Concurrent Mark-Sweep GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 12733906944 (12144.0MB)
   NewSize          = 2686976 (2.5625MB)
   MaxNewSize       = 130809856 (124.75MB)
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 4
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 176160768 (168.0MB)

Why are NewSize, MaxNewSize, OldSize, and PermSize all so small, when the MaxHeapSize is large? Shouldn't NewSize + OldSize = heap size? And shouldn't the overall heap size be approaching MaxHeapSize? Why is NewSize exactly half of OldSize when the NewRatio is set to 4?

The rest of the jmap output is below. It matches the above, and includes a section concurrent mark-sweep generation which I also don't know how to interpret.

Additionally, the GC logs indicate that the "desired survivor size" is 6.2MB, which is also strange given I understand -XX:SurvivorRatio=8 should make the survivor space 1/8 of NewSize.

Finally, I only ever see ParNew messages in my GC log, which I understand is the GC for Eden.


Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 117768192 (112.3125MB)
   used     = 20402232 (19.45708465576172MB)
   free     = 97365960 (92.85541534423828MB)
   17.324059793666528% used
Eden Space:
   capacity = 104726528 (99.875MB)
   used     = 16408336 (15.648208618164062MB)
   free     = 88318192 (84.22679138183594MB)
   15.667793359863893% used
From Space:
   capacity = 13041664 (12.4375MB)
   used     = 3993896 (3.8088760375976562MB)
   free     = 9047768 (8.628623962402344MB)
   30.624128945508794% used
To Space:
   capacity = 13041664 (12.4375MB)
   used     = 0 (0.0MB)
   free     = 13041664 (12.4375MB)
   0.0% used
concurrent mark-sweep generation:
   capacity = 12603097088 (12019.25MB)
   used     = 7903352408 (7537.22420501709MB)
   free     = 4699744680 (4482.02579498291MB)
   62.70960505037411% used
Perm Generation:
   capacity = 45903872 (43.77734375MB)
   used     = 27759192 (26.473228454589844MB)
   free     = 18144680 (17.304115295410156MB)
   60.472441191889% used

Best Answer

Why are NewSize, MaxNewSize, OldSize, and PermSize all so small, when the MaxHeapSize is large?

The sizes are only as large as they need to be. The NewSize will be larger if you generate more short lived garbage (I don't know how the MaxNewSize is set, but its usually smaller than what I set it to)

concurrent mark-sweep generation

This has the capacity = maximum size, used = used, free = capacity - used.

ParNew messages in my GC log, which I understand is the GC for Eden.

As you noted, the new space is small so it cleans up often and the old gen is large so it cleans up rarely if at all.

Related Topic