JDK-8030849 : Investigate high fragmentation/waste in some situations during allocation during GC in G1
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 9
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2013-12-20
  • Updated: 2022-04-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
G1 sometimes cannot prevent full GCs even with timely marking and mixed GCs. These occur intermittently with no immediately apparent cause. These full GCs are extremely bad for response times, as they (and the mixed GCs with to-space-exhaustions) are very slow.

Leading up to these GCs, as mentioned, there are typically many mixed GCs with their respective marking cycles, but these mixed GCs do not manage to reclaim anything, actually growing the heap.

There is the CRM Fuse benchmark where we particularly increased the heap region size (to 4M) to avoid very frequent large objects which G1 otherwise does not handle well at all at the moment.

Some initial investigation with -XX:+ParallelGCVerbose indicates that waste due to PLABs is already very high in the regular case (in total 8M for about 35-40M of copying into survivor or old gen), but extremely high in these cases when mixed GCs increases the heap size (>24M).

The current suspicion is that the allocators for the evacuation are not able to avoid waste; the PLAB resizing of G1 also likely contributes to that (PLABs may basically be additional large objects), but the main factor should be these frequent large objects (up to 2M) in the young gen, that cause G1 to retire the current allocation regions.

First, this situation must be investigated further, and the assumptions verified and some object size and fragmentation/waste information obtained; then some idea developed to mitigate this issue. Some possible solutions could be:
- limiting maximum PLAB size to decrease waste due to too large PLABs (if this is a problem)
- if the problem is the waste at the end of a region because of largish objects coming in: improve the allocator to not retire a region, but keep the tails available for further PLAB allocation, and just allocate the large object somewhere else
- analyze the current code that attempts to mitigate this issue (two allocation LABs per thread), maybe extending it
- something else

This is the umbrella issue resulting in further work/issues.
Comments
Need to re-baseline too. Some of the issues above may have very well been covered by changes for JDK9.
03-05-2016

Changing this to a task collecting references to issues only.
05-02-2016

Attached gcmicro.tar.gz contains GCMicro.jar and config.gcMicro. This micro shows too small PLAB can cause spike in system cpu usage. jvm parameters: -server -Xms16g -Xmx16g -Xmn10g -XX:+UseG1GC -XX:-UseAdaptiveSizePolicy -XX:-UseLargePages -XX:-TieredCompilation -XX:-UseBiasedLocking -XX:+UnlockExperimentalVMOptions -XX:InitiatingHeapOccupancyPercent=90 -XX:G1RSetUpdatingPauseTimePercent=2 -XX:MaxGCPauseMillis=600 -XX:G1HeapWastePercent=2 -XX:G1MixedGCLiveThresholdPercent=85 -XX:G1HeapRegionSize=16m -XX:G1MixedGCCountTarget=4 -XX:G1OldCSetRegionThresholdPercent=30 -XX:MaxTenuringThreshold=15 -XX:TargetSurvivorRatio=90 -XX:+AlwaysPreTouch -XX:SurvivorRatio=8 -XX:ParallelGCThreads=8 I run 4 cases [0] -XX:-ResizePLAB [1] -XX:+ResizePLAB [2] -XX:-ResizePLAB -XX:OldPLABSize=2097152 -XX:YoungPLABSize=2097152 [3] -XX:-ResizePLAB -XX:OldPLABSize=0 -XX:YoungPLABSize=0 For this test, [2] has the best results. However, we can not give too big PLAB size, due to too much wasted. Finding the sweet spot is tricky.
29-05-2014

One idea to decrease the amount of unused space is to not allocate/retire PLABs multiple times within a single GC, only allocate at the beginning and then retire at the end.
17-02-2014

Not sure if PLAB allocation already does, but if the waste of the end of a region is a problem, and is caused by PLABs, one could size them "elastically", i.e. just get the remaining space that is larger than the allocation size that caused the allocation.
20-12-2013

It seems that it is useful to limit PLAB sizes by e.g. some fraction of a heap region so that they do not act as large objects themselves in the end. Given a "large enough" limit for that size, the performance impact should be very small. Manually setting PLAB sizes should be a reasonable workaround for the time being when this issue has been found too.
20-12-2013

JDK-6976350 should have fixed these situations, but it did not. Looking at this CR, the actual implementation implements a far simpler idea than described in the comments, i.e. a fixed amount of allocation buffers instead of a dynamic one. However that proposed idea does not seem to scale with machines with many amounts threads, as still every thread may theoretically allocate an infinite amount of private buffers containing waste. I.e. other threads will never get the opportunity to fill fragmentation induced by other threads.
20-12-2013

Just as an interesting data point: in the attached log file, the average waste per thread and per gc is ~650kb - at 18 threads there is almost 12MB of wasted space on average per GC. That seems to be a considerable part of the actually allocated space during GC (This average includes all types of young GC)
20-12-2013