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> \progra~1\java\jdk1.8.0\bin\java -Xms360m -Xmx360m \
   -XX:NewRatio=1 -XX:SurvivorRatio=1 \
   -XX:+UseSerialGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC \
   -XX:+PrintTenuringDistribution GarbageCollection2

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

{Heap before GC invocations=0 (full 0):
 def new generation   total 122880K, used 60826K [...
  eden space 61440K,  99% used [...
  from space 61440K,   0% used [...
  to   space 61440K,   0% used [...
 tenured generation   total 184320K, used 0K [...
   the space 184320K,   0% used [...
 Metaspace used 1567K, capacity 2242K, committed 2368K, reserved 4480K

[GC (Allocation Failure) [DefNew
Desired survivor size 31457280 bytes, new threshold 15 (max 15)
- age   1:   26467640 bytes,   26467640 total
: 60826K->25847K(122880K), 0.0208674 secs]
   60826K->25847K(307200K), 0.0209314 secs]

Heap after GC invocations=1 (full 0):
 def new generation   total 122880K, used 25847K [...
  eden space 61440K,   0% used [...
  from space 61440K,  42% used [...
  to   space 61440K,   0% used [...
 tenured generation   total 184320K, used 0K [...
   the space 184320K,   0% used [...
 Metaspace used 1567K, capacity 2242K, committed 2368K, reserved 4480K
}

But at the second GC. 50% of survivor 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.

{Heap before GC invocations=1 (full 0):
 def new generation   total 122880K, used 86444K [...
  eden space 61440K,  98% used [...
  from space 61440K,  42% used [...
  to   space 61440K,   0% used [...
 tenured generation   total 184320K, used 0K [...
   the space 184320K,   0% used [...
 Metaspace used 1567K, capacity 2242K, committed 2368K, reserved 4480K

[GC (Allocation Failure) [DefNew
Desired survivor size 31457280 bytes, new threshold 2 (max 15)
- age   1:   28311984 bytes,   28311984 total
- age   2:    3398136 bytes,   31710120 total
: 86444K->30966K(122880K), 0.0340368 secs]
   86444K->30966K(307200K), 0.0340731 secs]

Heap after GC invocations=2 (full 0):
 def new generation   total 122880K, used 30966K [...
  eden space 61440K,   0% used [...
  from space 61440K,  50% used [...
  to   space 61440K,   0% used [...
 tenured generation   total 184320K, used 0K [...
   the space 184320K,   0% used [...
 Metaspace used 1567K, capacity 2242K, committed 2368K, reserved 4480K
}

At the third GC, the survivor space usage went back to 48%. So Serial collector decided to set the tenuring threshold back to 15.

{Heap before GC invocations=2 (full 0):
 def new generation   total 122880K, used 91566K [...
  eden space 61440K,  98% used [...
  from space 61440K,  50% used [...
  to   space 61440K,   0% used [...
 tenured generation   total 184320K, used 0K [...
   the space 184320K,   0% used [...
 Metaspace used 1567K, capacity 2242K, committed 2368K, reserved 4480K

[GC (Allocation Failure) [DefNew
Desired survivor size 31457280 bytes, new threshold 15 (max 15)
- age   1:   29360576 bytes,   29360576 total
- age   2:    1048592 bytes,   30409168 total
: 91566K->29696K(122880K), 0.0151026 secs]
   91566K->31990K(307200K), 0.0151380 secs]

Heap after GC invocations=3 (full 0):
 def new generation   total 122880K, used 29696K [...
  eden space 61440K,   0% used [...
  from space 61440K,  48% used [...
  to   space 61440K,   0% used [...
 tenured generation   total 184320K, used 2294K [...
   the space 184320K,   1% used [...
 Metaspace used 1567K, capacity 2242K, committed 2368K, reserved 4480K
}

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

 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

 Archived Tutorials

 References

 Full Version in PDF/EPUB