Order
This article mainly studiesJEP 248: Make G1 the Default Garbage Collector
Default garbage collector
Java9 abandoned the CMS garbage collector and upgraded G1 to the default garbage collector, replacing the original throughput-first ParallelOldGC
Region
The biggest difference between G1 and previous garbage collectors is the introduction of Region. G1 is also based on generation mechanism, but the space of each generation is no longer continuous, as shown in the following figure:
Region Size can be specified with-xx: g1hepregionsize = 16m, note that it must be a power of 2, ranging from 1MB to 32MB. The goal is to divide about 2048 regions according to the smallest Java heap size.
If it is not explicitly specified, it is automatically specified according to Heap Size, and the corresponding relationship is as follows:
Min Heap Size | Region Size |
---|---|
heap < 4GB | 1MB |
4GB <= heap < 8GB | 2MB |
8GB <= heap < 16GB | 4MB |
16GB <= heap < 32GB | 8MB |
32GB <= heap < 64GB | 16MB |
64GB <= heap | 32MB |
Humongousobject/region
- For G1 GC, any object larger than half the area size is considered a “giant object.”
- Such objects are directly allocated to “giant areas” in the old days.
- These giant regions are a continuous set of regions. StartsHumongous marks the beginning of the continuous set and continuations humanous marks its continuation.
Giant objects will be allocated directly to the elderly by default, but if it is a short-term giant object, it will have a negative impact on the garbage collector. In order to solve this problem, G1 divides a Humongous area, which is dedicated to storing giant objects. If an H area cannot hold a giant object, G1 will look for consecutive H areas to store. In order to find the continuous H zone, sometimes you have to start Full GC.
GC events and triggers
GC event
- Minor GC event
Normal young gc
- Mixed GC event
Minor GC + (# reclaimable Tenured regions / -XX:G1MixedGCCountTarget) regions of Tenured
- Full GC event
All regions evacuated, usually too many humanousobjects deplete space, resulting in Full GC
- Minor/Mixed + To-space exhaustion
Minor/Mixed + rollback + Full GC
Trigger timing
- Eden is full/out of space.
- There is not enough space left to accommodate a humanousobject.
- Humongous object allocation succeeded and met some GC conditions.
- External command triggering (jcmd, jmap, Runtime.gc ())
G1 GC classification
Mainly divided into: Minor GC, Mixed/Old GC
Minor GC/Young GC(STW
)
Young GC mainly performs GC on Eden area, which will be triggered when Eden space is insufficient. The data in Eden space is moved to Survivor space. If Survivor space is insufficient, some data in Eden space will be directly promoted to the old generation space. Data From Survivor area are moved To Survivor area, and some data are promoted to the space of old age.
The main stages are as follows:
Stage | Perform an action |
---|---|
Phase 1 root scan | Static and local objects are scanned |
Phase 2 update RS | Handling dirty card queue updates RS |
Stage 3 processing RS | Detecting objects from the younger generation to the older generation |
Phase 4 Object Copy | Copy surviving objects to survivor/old area |
Phase 5 processes the reference queue | Soft Reference, Weak Reference, Virtual Reference Processing |
Mixed/Old GC(STW
)
It is mainly to mark the old generation concurrently and then perform GC. Some of the phases involve ygc, while some of the existing ygc and old gc are called mixed gc.
The Concurrent Marking Cycle Phases are as follows:
Stage | Perform an action |
---|---|
(1) initial mark (stop the world event) initial marking phase | At this stage G1 GC marks the root. This stage is closely related to the conventional (STW) recycling of young generation garbage. The log is marked as pause initialmark (g1evaluation pause). |
(2) Root Region Scanning root region scanning phase | G1 GC scans the reference to the old age in the survival area of the initial mark and marks the referenced object. This phase runs simultaneously with the application (non-STW), and the next STW young generation garbage collection cannot start until this phase is completed. |
(3) Concurrent Marking phase | G1 GC looks for accessible (surviving) objects throughout the heap. This phase runs simultaneously with the application and can be interrupted by STW’s young generation garbage collection. |
(4) Remark(Stop the World Event) Remark Stage | This stage is STW recycling to help complete the marking cycle. G1 GC empties SATB buffer, tracks the surviving objects that have not been accessed, and performs reference processing. |
(5) Copying/cleaning phase | In this final stage, G1 GC will select regions with low survival rate to copy, i.e. evacuate or copy the surviving objects to the new free regions, and then clean up and recycle the regions. at this time, it will STW. if it is generated in a younger generation, the log will be marked as Pause Young (G1 Evacuation Pause). If both the younger generation and the older generation perform this action, the log is marked as Pause Mixed (G1 Evacuation Pause). |
The core stages are mainly Concurrent Marking Phase, Remark Phase, Copying/Cleanup Phase.
Related parameters
Parameter | Meaning |
---|---|
-XX:G1HeapRegionSize=n | Set Region Size, Not Final |
-XX:MaxGCPauseMillis=200 | Set G1 collection process target time, default value 200ms, not a hard condition |
-XX:G1NewSizePercent=5 | Cenozoic minimum value, default value 5% |
-XX:G1MaxNewSizePercent=60 | Cenozoic maximum value, default value 60% |
-XX:ParallelGCThreads=n | During STW, the number of parallel GC threads is the same as the number of logical processors, up to 8. If there are more than eight logical processors, then n is 5/8 of the number of logical processors. |
-XX:ConcGCThreads=n | The number of parallel marking threads in the concurrent marking phase is about 1/4 of that of ParallelGCThreads. |
-XX:InitiatingHeapOccupancyPercent=45 | Set the Java heap occupancy threshold that triggers the mark period. The default value is 45%. The java heap ratio here refers to non_young_capacity_bytes, including old+humongous |
-XX:G1MixedGCLiveThresholdPercent=65 | Set occupancy thresholds for old areas to be included in the mixed garbage collection cycle. The default occupancy rate is 65% |
-XX:G1HeapWastePercent=10 | If the recoverable percentage is less than this value, the JVM will not start the mixed garbage collection cycle. The default value is 10% |
-XX:G1OldCSetRegionThresholdPercent=10 | Set the maximum number of old areas to recycle during mixed garbage collection. The default value is 10% of the Java heap |
-XX:G1MixedGCCountTarget=8 | After the marking period is set, the target number of times mixed garbage collection is performed on the old area with the upper limit of survival data G1MixedGCLIveThresholdPercent. The default is 8 times of mixed garbage collection. The target of mixed garbage collection is to control within this target number of times. |
-XX:G1ReservePercent=10 | Set the percentage of memory reserved as free space to reduce the risk of overflow of target space. The default value is 10%. When increasing or decreasing the percentage, be sure to adjust the total Java heap by the same amount |
Avoid using the -Xmn option or other relevant options such as -XX:NewRatio to explicitly set the size of the younger generation. fixing the size of the younger generation will disable the MaxGCPauseMillis target.
GC log instance
The simple version uses -Xlog:gc=info, while the detailed version uses -Xlog:gc*=info
ygc
- Simple edition
[0.317s][info][gc] GC(37) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.511ms
[0.324s][info][gc] GC(40) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.709ms
- Detailed edition
[0.011s][info][gc,heap] Heap region size: 1M
[0.012s][info][gc ] Using G1
[0.012s][info][gc,heap,coops] Heap address: 0x00000007bf600000, size: 10 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
[0.170s][info][gc,start ] GC(0) Pause Young (G1 Evacuation Pause)
[0.170s][info][gc,task ] GC(0) Using 8 workers of 8 for evacuation
[0.172s][info][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.0ms
[0.172s][info][gc,phases ] GC(0) Evacuate Collection Set: 1.5ms
[0.172s][info][gc,phases ] GC(0) Post Evacuate Collection Set: 0.1ms
[0.172s][info][gc,phases ] GC(0) Other: 0.1ms
[0.172s][info][gc,heap ] GC(0) Eden regions: 4->0(2)
[0.172s][info][gc,heap ] GC(0) Survivor regions: 0->1(1)
[0.172s][info][gc,heap ] GC(0) Old regions: 0->1
[0.172s][info][gc,heap ] GC(0) Humongous regions: 0->0
[0.172s][info][gc,metaspace ] GC(0) Metaspace: 5982K->5982K(1056768K)
[0.172s][info][gc ] GC(0) Pause Young (G1 Evacuation Pause) 4M->1M(10M) 1.718ms
[0.172s][info][gc,cpu ] GC(0) User=0.01s Sys=0.00s Real=0.00s
old gc
- Simple edition
[0.321s][info][gc] GC(38) Pause Initial Mark (G1 Evacuation Pause) 7M->6M(10M) 0.601ms
[0.321s][info][gc] GC(39) Concurrent Cycle
[0.324s][info][gc] GC(40) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.709ms
[0.326s][info][gc] GC(39) Pause Remark 7M->7M(10M) 0.623ms
[0.326s][info][gc] GC(39) Pause Cleanup 7M->7M(10M) 0.104ms
[0.326s][info][gc] GC(39) Concurrent Cycle 5.398ms
[0.327s][info][gc] GC(41) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.512ms
[0.331s][info][gc] GC(42) To-space exhausted
[0.331s][info][gc] GC(42) Pause Mixed (G1 Evacuation Pause) 7M->7M(10M) 1.190ms
[0.334s][info][gc] GC(43) Pause Initial Mark (G1 Evacuation Pause) 8M->7M(10M) 0.637ms
[0.334s][info][gc] GC(44) Concurrent Cycle
[0.338s][info][gc] GC(45) Pause Young (G1 Evacuation Pause) 8M->7M(10M) 0.553ms
[0.340s][info][gc] GC(44) Pause Remark 8M->8M(10M) 0.582ms
[0.341s][info][gc] GC(44) Pause Cleanup 8M->8M(10M) 0.100ms
[0.341s][info][gc] GC(44) Concurrent Cycle 6.195ms
- Detailed edition
[0.942s][info][gc,start ] GC(192) Pause Initial Mark (G1 Evacuation Pause)
[0.942s][info][gc,task ] GC(192) Using 8 workers of 8 for evacuation
[0.942s][info][gc,phases ] GC(192) Pre Evacuate Collection Set: 0.0ms
[0.942s][info][gc,phases ] GC(192) Evacuate Collection Set: 0.4ms
[0.942s][info][gc,phases ] GC(192) Post Evacuate Collection Set: 0.0ms
[0.942s][info][gc,phases ] GC(192) Other: 0.0ms
[0.942s][info][gc,heap ] GC(192) Eden regions: 0->0(1)
[0.942s][info][gc,heap ] GC(192) Survivor regions: 0->0(1)
[0.942s][info][gc,heap ] GC(192) Old regions: 10->10
[0.942s][info][gc,heap ] GC(192) Humongous regions: 0->0
[0.942s][info][gc,metaspace ] GC(192) Metaspace: 5993K->5993K(1056768K)
[0.942s][info][gc ] GC(192) Pause Initial Mark (G1 Evacuation Pause) 9M->9M(10M) 0.530ms
[0.942s][info][gc,cpu ] GC(192) User=0.00s Sys=0.00s Real=0.00s
[0.942s][info][gc ] GC(193) Concurrent Cycle
[0.942s][info][gc,marking ] GC(193) Concurrent Clear Claimed Marks
[0.942s][info][gc,marking ] GC(193) Concurrent Clear Claimed Marks 0.004ms
[0.942s][info][gc,marking ] GC(193) Concurrent Scan Root Regions
[0.942s][info][gc,marking ] GC(193) Concurrent Scan Root Regions 0.003ms
[0.942s][info][gc,marking ] GC(193) Concurrent Mark (0.942s)
[0.942s][info][gc,marking ] GC(193) Concurrent Mark From Roots
[0.942s][info][gc,task ] GC(193) Using 2 workers of 2 for marking
[0.942s][info][gc,start ] GC(194) Pause Full (Allocation Failure)
[0.943s][info][gc,phases,start] GC(194) Phase 1: Mark live objects
[0.946s][info][gc,stringtable ] GC(194) Cleaned string and symbol table, strings: 3222 processed, 0 removed, symbols: 25923 processed, 0 removed
[0.946s][info][gc,phases ] GC(194) Phase 1: Mark live objects 3.168ms
[0.946s][info][gc,phases,start] GC(194) Phase 2: Compute new object addresses
[0.946s][info][gc,phases ] GC(194) Phase 2: Compute new object addresses 0.418ms
[0.946s][info][gc,phases,start] GC(194) Phase 3: Adjust pointers
[0.949s][info][gc,phases ] GC(194) Phase 3: Adjust pointers 2.706ms
[0.949s][info][gc,phases,start] GC(194) Phase 4: Move objects
[0.949s][info][gc,phases ] GC(194) Phase 4: Move objects 0.005ms
[0.949s][info][gc,task ] GC(194) Using 8 workers of 8 to rebuild remembered set
[0.951s][info][gc,heap ] GC(194) Eden regions: 0->0(1)
[0.951s][info][gc,heap ] GC(194) Survivor regions: 0->0(1)
[0.951s][info][gc,heap ] GC(194) Old regions: 10->10
[0.951s][info][gc,heap ] GC(194) Humongous regions: 0->0
[0.951s][info][gc,metaspace ] GC(194) Metaspace: 5993K->5993K(1056768K)
[0.951s][info][gc ] GC(194) Pause Full (Allocation Failure) 9M->9M(10M) 8.955ms
[0.951s][info][gc,cpu ] GC(194) User=0.01s Sys=0.00s Real=0.01s
Summary
G1 collector is extensive and profound, and needs further practice for further understanding and research.
doc
- JDK 9 features
- JEP 248: Make G1 the Default Garbage Collector
- JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
- JEP 278: Additional Tests for Humongous Objects in G1
- Getting Started with the G1 Garbage Collector
- G1GC Fundamentals: Lessons from Taming Garbage Collection
- Optimization of Garbage Priority Garbage Reclaimer
- Deep understanding of Java G1 garbage collector
- GC tuning foundation in Java 9
- Some key technologies of Java Hotspot G1 GC
- Understanding and Principle Analysis of Garbage First G1 Collector
- Tuning Java Garbage Collection for Apache Spark Applications