Question

I am working on resolving a high garbage collection utilization rate in our production environment, and was wondering if setting a large heap size guaranteeing that the old generation will never be really filled up would prevent triggering a major GC cycle.

For that to be true, I imagine that there is a certain threshold mark at which a major GC cycle gets triggered. If this assumption is true, can someone please let me know what that number is? If not, I would appreciate an explanation of how these major cycles are actually triggered and if my large heap strategy has a potential of working.

Was it helpful?

Solution

Concurrent Mark Sweep

Assuming you use Concurrent Mark Sweep collector (e.g. -XX:+UseConcMarkSweepGC), it, by default, starts to collect concurrently when OldGen reaches 70%. But it is tunable via CMSInitiatingOccupancyFraction e.g.:

-XX:CMSInitiatingOccupancyFraction=42

this will start concurrent collection at 42% vs. the default 70%

Note that CMSInitiatingOccupancyFraction will only be in effect for the first collection. To enable it "for good" add UseCMSInitiatingOccupancyOnly:

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=42

Max Heap Free Ratio

You can also look at MaxHeapFreeRatio that is a maximum percentage of heap free after GC to avoid shrinking, which is set to 70% by default, but you can change that as well:

-XX:MaxHeapFreeRatio=42

Getting to the bottom

But before changing any params, it would be good to understand the reason for this "high garbage collection utilization rate":

  • Why does it get to the OldGen if it needs to be collected so often?
  • Are you capturing streaming data?
  • Does a heap size too small for a problem?
  • Does it make sense to store this particular data off heap?
  • etc..

Since usually JVM is quite good at knowing when to collect, and it's only getting better.


other HоtSpot VM options

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top