"-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

 About This Book

 Heap Memory Area and Size Control

 JVM Garbage Collection Logging

 Introduction of Garbage Collectors

Serial Collector - "+XX:+UseSerialGC"

 What Is Serial Collector

 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

 Garbage Collection Performance Test Summary

 References

 Full Version in PDF/EPUB