问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/23176974/how-full-does-the-old-generation-have-to-be-to-trigger-a-major-gc-cycle