Java GC Tutorials - Herong's Tutorial Examples - v1.11, by Dr. Herong Yang
"-XX:TargetSurvivorRatio" - Second Tenuring Condition
This section describes the '-XX:TargetSurvivorRatio' JVM option, with sets the maximum survivor space usage percentage. When this limit is reached, all remaining live objects will be promoted to Tenured generation regardless of their age.
In previous tutorials, we learned the first condition of live object tenuring (promoted from survivor space into Tenured generation). When a live object has reached the tenuring threshold age, it will be promoted into Tenured generation.
However, there another condition that triggers object tenuring. When the survivor space usage has reached target ratio defined by another option called "-XX:TargetSurvivorRatio", remaining live objects, regardless of their age, will be promoted into Tenured generation. This case is also called premature tenuring (or premature promotion).
The Serial collector, uses "-XX:TargetSurvivorRatio=50" as the default, which says, I need to keep my survivor space usage below 50%. This seems to be a big waste of heap memory.
Let's run our first test with "-XX:TargetSurvivorRatio=50" on our test program GarbageCollection2.java.
herong> java -Xms360m -Xmx360m -XX:+UseSerialGC \ -XX:NewRatio=1 -XX:SurvivorRatio=1 \ -XX:TargetSurvivorRatio=50 \ -Xlog:gc=info,gc+heap=debug,gc+age=trace GarbageCollection2 ... 153 314572800 219805944 94766856 [debug][gc,heap] GC(2) Heap before GC invocations=2 (full 0): def new generation total 122880K, used 92545K ... [debug][gc,heap] GC(2) eden space 61440K, 99% used [... [debug][gc,heap] GC(2) from space 61440K, 51% used [... [debug][gc,heap] GC(2) to space 61440K, 0% used [... [debug][gc,heap] GC(2) tenured generation total 184320K, used 0K ... [debug][gc,heap] GC(2) the space 184320K, 0% used [... [debug][gc,age ] GC(2) Desired survivor size 31457280 bytes, new threshold 15 (max threshold 15) [trace][gc,age ] GC(2) Age table with threshold 15 (max threshold 15) [trace][gc,age ] GC(2) - age 1: 26214800 bytes, 26214800 total [trace][gc,age ] GC(2) - age 2: 4195240 bytes, 30410040 total [info ][gc,heap] GC(2) DefNew: 92545K->29697K(122880K) [info ][gc,heap] GC(2) Tenured: 0K->4924K(184320K) [info ][gc ] GC(2) Pause Young (Allocation Failure) 90M->33M(300M) 13.031ms [debug][gc,heap] GC(2) Heap after GC invocations=3 (full 0): def new generation total 122880K, used 29697K ... [debug][gc,heap] GC(2) eden space 61440K, 0% used [... [debug][gc,heap] GC(2) from space 61440K, 48% used [... [debug][gc,heap] GC(2) to space 61440K, 0% used [... [debug][gc,heap] GC(2) tenured generation total 184320K, used 4924K ... [debug][gc,heap] GC(2) the space 184320K, 2% used [...
As you can see from the output, the third Minor GC promoted 4924K objects to "tenured" generation prematurely. This was because the "from" space usage reached 51% after the previous GC, see "from space 61440K, 51% used" in the "Heap before GC" message section. 51% was higher than TargetSurvivorRatio of 50%, "age 3" were promoted to "tenured" generation.
Now rerun the test with "-XX:TargetSurvivorRatio=70". And we can also lower the survivor space to 50MB.
herong> java -Xms300m -Xmx300m -XX:+UseSerialGC \ -XX:NewRatio=1 -XX:SurvivorRatio=1 \ -XX:TargetSurvivorRatio=70 \ -Xlog:gc=info,gc+heap=debug,gc+age=trace GarbageCollection2 ... 705 262144000 174282368 87861632 [debug][gc,heap] GC(14) Heap before GC invocations=14 (full 0): def new generation total 102400K, ... [debug][gc,heap] GC(14) eden space 51200K, 99% used [... [debug][gc,heap] GC(14) from space 51200K, 67% used [... [debug][gc,heap] GC(14) to space 51200K, 0% used [... [debug][gc,heap] GC(14) tenured generation total 153600K, ... [debug][gc,heap] GC(14) the space 153600K, 0% used [... [debug][gc,age ] GC(14) Desired survivor size 36700160 bytes, new threshold 15 (max threshold 15) [trace][gc,age ] GC(14) Age table with threshold 15 (max threshold 15) [trace][gc,age ] GC(14) - age 1: 23069024 bytes, 23069024 total [trace][gc,age ] GC(14) - age 2: 6291688 bytes, 29360712 total [trace][gc,age ] GC(14) - age 3: 2097184 bytes, 31457896 total [trace][gc,age ] GC(14) - age 4: 192 bytes, 31458088 total [trace][gc,age ] GC(14) - age 6: 1048592 bytes, 32506680 total [trace][gc,age ] GC(14) - age 13: 80 bytes, 32506760 total [trace][gc,age ] GC(14) - age 14: 792 bytes, 32507552 total [trace][gc,age ] GC(14) - age 15: 2945936 bytes, 35453488 total [info ][gc,heap] GC(14) DefNew: 85802K->34622K(102400K) [info ][gc,heap] GC(14) Tenured: 0K->0K(153600K) [info ][gc ] GC(14) Pause Young (Allocation Failure) 83M->33M(250M) 9.807ms [debug][gc,heap] GC(14) Heap after GC invocations=15 (full 0): def new generation total 102400K, ... [debug][gc,heap] GC(14) eden space 51200K, 0% used [... [debug][gc,heap] GC(14) from space 51200K, 67% used [... [debug][gc,heap] GC(14) to space 51200K, 0% used [... [debug][gc,heap] GC(14) tenured generation total 153600K, ... [debug][gc,heap] GC(14) the space 153600K, 0% used [...
As you can see from the output, no objects got promoted to "tenured" generation yet after 15 rounds of GC. The "from" space usage was lower than 70% and no objects lived longer than age 15. But at the next GC, some of "age 15" objects will be promoted to "tenured" generation, because of their maturity.
Conclusion:
Table of Contents
Heap Memory Area and Size Control
JVM Garbage Collection Logging
Introduction of Garbage Collectors
►Serial Collector - "+XX:+UseSerialGC"
GC Log Message Format for Serial Collector
GC Log Message Examples of Serial Collector
Log Message Types from Serial Collector
Serial Collector Stops Application for Minor/Major GC
Usage Report on Heap Memory Areas
Default NewRatio - Old vs. New Generation
"-XX:NewRatio" - Ratio of Tenured and "new" Generation
"-XX:SurvivorRatio" - Ratio of Eden and Survivor Space
Serial GC Tracing - Tight Heap
Serial GC Tracing - Tight Heap (Part 2)
Serial GC Tracing - Tight Heap (Part 3)
Serial GC Tracing - Plenty of Heap
Serial GC Tracing - Aged Live Objects
Serial GC Tracing - Tenuring Threshold
►"-XX:TargetSurvivorRatio" - Second Tenuring Condition
Serial GC Tracing - Tenuring Threshold Controlled
"-XX:+NeverTenure" and "-XX:+AlwaysTenure" Working
Minor GC Triggering Condition of Serial Collector
Parallel Collector - "+XX:+UseParallelGC"
Concurrent Mark-Sweep (CMS) Collector - "+XX:+UseConcMarkSweepGC"
Garbage First (G1) Collector - "+XX:+UseG1GC"
The Z Garbage Collector (ZGC) - "+XX:+UseZGC"
Object References and Garbage Collection
Garbage Collection Performance Test Program
Performance Tests on Serial Collector
Performance Tests on Parallel collector
Performance Tests on Concurrent collector
Performance Tests on G1 collector