Serial GC Tracing - Tenuring Threshold

This section provides a tutorial showing how Serial GC changes the tenuring threshold dynamically and promotes objects to 'tenured' generation earlier or later to Tenuring generation to meet the TargetSurvivorRatio setting.

In the previous tutorial, we learned that when a live object survived Minor GC multiple times and reached the tenuring threshold age, it will be promoted to Tenured generation.

But the Serial collector can also change the tenuring threshold age dynamically based on past GC statistics. This is to move object out of the survivor space quickly to avoid survivor space overflow.

Let's rerun the same test with a smaller survivor space.

herong> java -Xms360m -Xmx360m -XX:+UseSerialGC \
   -XX:NewRatio=1 -XX:SurvivorRatio=1 \
   -Xlog:gc=info,gc+heap=debug,gc+age=trace GarbageCollection

At the first Minor GC, the survivor ("from") space usage was 43%. There is no danger of overflow, so Serial collector kept the tenuring threshold to age 15, the default age.

...
35   314572800   252468808   62103992
[debug][gc,heap] GC(0) Heap before GC invocations=0 (full 0):
                        def new generation   total 122880K, used 60648K ...
[debug][gc,heap] GC(0)   eden space 61440K,  98% used [...
[debug][gc,heap] GC(0)   from space 61440K,   0% used [...
[debug][gc,heap] GC(0)   to   space 61440K,   0% used [...
[debug][gc,heap] GC(0)  tenured generation   total 184320K, used 0K ...
[debug][gc,heap] GC(0)    the space 184320K,   0% used [...

[debug][gc,age ] GC(0) Desired survivor size 31457280 bytes,
                       new threshold 15 (max threshold 15)
[trace][gc,age ] GC(0) Age table with threshold 15 (max threshold 15)
[trace][gc,age ] GC(0) - age   1:   27076584 bytes,   27076584 total

[info ][gc,heap] GC(0) DefNew: 60648K->26441K(122880K)
[info ][gc,heap] GC(0) Tenured: 0K->0K(184320K)
[info ][gc     ] GC(0) Pause Young (Allocation Failure)
                       59M->25M(300M) 23.512ms

[debug][gc,heap] GC(0) Heap after GC invocations=1 (full 0):
                        def new generation   total 122880K, used 26441K ...
[debug][gc,heap] GC(0)   eden space 61440K,   0% used [...
[debug][gc,heap] GC(0)   from space 61440K,  43% used [...
[debug][gc,heap] GC(0)   to   space 61440K,   0% used [...
[debug][gc,heap] GC(0)  tenured generation   total 184320K, used 0K ...
[debug][gc,heap] GC(0)    the space 184320K,   0% used [...

But at the second GC. 54% of survivor ("from") space was used. It reached another setting called TargetSurvivorRatio, which is defaulted to 50%. So Serial collector decided to lower the tenuring threshold age to 2. This forces all objects older than 3 to be promoted to Tenured generation at next GC.

...
94   314572800   224816184   89756616
[debug][gc,heap] GC(1) Heap before GC invocations=1 (full 0):
                        def new generation   total 122880K, used 87652K ...
[debug][gc,heap] GC(1)   eden space 61440K,  99% used [...
[debug][gc,heap] GC(1)   from space 61440K,  43% used [...
[debug][gc,heap] GC(1)   to   space 61440K,   0% used [...
[debug][gc,heap] GC(1)  tenured generation   total 184320K, used 0K ...
[debug][gc,heap] GC(1)    the space 184320K,   0% used [...

[debug][gc,age ] GC(1) Desired survivor size 31457280 bytes,
                       new threshold 2 (max threshold 15)
[trace][gc,age ] GC(1) Age table with threshold 2 (max threshold 15)
[trace][gc,age ] GC(1) - age   1:   28312856 bytes,   28312856 total
[trace][gc,age ] GC(1) - age   2:    6091464 bytes,   34404320 total

[info ][gc,heap] GC(1) DefNew: 87652K->33597K(122880K)
[info ][gc,heap] GC(1) Tenured: 0K->0K(184320K)
[info ][gc     ] GC(1) Pause Young (Allocation Failure)
                       85M->32M(300M) 18.668ms

[debug][gc,heap] GC(1) Heap after GC invocations=2 (full 0):
                        def new generation   total 122880K, used 33597K ...
[debug][gc,heap] GC(1)   eden space 61440K,   0% used [...
[debug][gc,heap] GC(1)   from space 61440K,  54% used [...
[debug][gc,heap] GC(1)   to   space 61440K,   0% used [...
[debug][gc,heap] GC(1)  tenured generation   total 184320K, used 0K ...
[debug][gc,heap] GC(1)    the space 184320K,   0% used [...

Later at the fourth GC, the survivor ("from") space usage went back to 48%. So Serial collector decided to set the tenuring threshold back to 15.

212   314572800   217064352   97508448
[debug][gc,heap] GC(3) Heap before GC invocations=3 (full 0):
                        def new generation   total 122880K, used 91322K ...
[debug][gc,heap] GC(3)   eden space 61440K,  98% used [...
[debug][gc,heap] GC(3)   from space 61440K,  50% used [...
[debug][gc,heap] GC(3)   to   space 61440K,   0% used [...
[debug][gc,heap] GC(3)  tenured generation   total 184320K, used 3900K ...
[debug][gc,heap] GC(3)    the space 184320K,   2% used [...

[debug][gc,age ] GC(3) Desired survivor size 31457280 bytes,
                       new threshold 15 (max threshold 15)
[trace][gc,age ] GC(3) Age table with threshold 15 (max threshold 15)
[trace][gc,age ] GC(3) - age   1:   27263392 bytes,   27263392 total
[trace][gc,age ] GC(3) - age   2:    3145776 bytes,   30409168 total

[info ][gc,heap] GC(3) DefNew: 91322K->29696K(122880K)
[info ][gc,heap] GC(3) Tenured: 3900K->4925K(184320K)
[info ][gc     ] GC(3) Pause Young (Allocation Failure)
                       92M->33M(300M) 6.884ms

[debug][gc,heap] GC(3) Heap after GC invocations=4 (full 0):
                        def new generation   total 122880K, used 29696K ...
[debug][gc,heap] GC(3)   eden space 61440K,   0% used [...
[debug][gc,heap] GC(3)   from space 61440K,  48% used [...
[debug][gc,heap] GC(3)   to   space 61440K,   0% used [...
[debug][gc,heap] GC(3)  tenured generation   total 184320K, used 4925K ...
[debug][gc,heap] GC(3)    the space 184320K,   2% used [...

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