Serial GC Tracing - Tight Heap (Part 3)

This section provides part 3 of a tutorial on tracing how Serial GC works with a tight heap size.

The sixth GC happened as a Full GC after another 9 iterations, because the "eden" space was 99% full again with new objects.

```25   40566784   9694584   30872200
26   40566784   8622920   31943864
27   40566784   7551256   33015528
28   40566784   6463192   34103592
29   40566784   5325976   35240808
30   40566784   4254312   36312472
31   40566784   3166248   37400536
32   40566784   2029032   38537752
33   40566784   1008048   39558736
[debug][gc,heap] GC(5) Heap before GC invocations=4 (full 1):
def new generation   total 12288K, used 12032K [...
[debug][gc,heap] GC(5)   eden space 10944K, 100% used [...
[debug][gc,heap] GC(5)   from space 1344K,  80% used [...
[debug][gc,heap] GC(5)   to   space 1344K,   0% used [...
[debug][gc,heap] GC(5)  tenured generation   total 27328K, used 27111K [...
[debug][gc,heap] GC(5)    the space 27328K,  99% used [...

[info ][gc,heap] GC(5) DefNew: 12032K->9649K(12288K)
[info ][gc,heap] GC(5) Tenured: 27111K->27316K(27328K)
[info ][gc     ] GC(5) Pause Full (Allocation Failure) 38M->36M(38M) 30.705ms

[debug][gc,heap] GC(5) Heap after GC invocations=5 (full 2):
def new generation   total 12288K, used 9649K [...
[debug][gc,heap] GC(5)   eden space 10944K,  88% used [...
[debug][gc,heap] GC(5)   from space 1344K,   0% used [...
[debug][gc,heap] GC(5)   to   space 1344K,   0% used [...
[debug][gc,heap] GC(5)  tenured generation   total 27328K, used 27316K [...
[debug][gc,heap] GC(5)    the space 27328K,  99% used [...
```

Notes on the above GC:

• This GC was triggered by 100% usage of "eden" space. It should be a Young GC. But there is no room left to promote live objects from "young" generation to "tenured" generation, a Full GC was executed.
• Since almost all objects in "tenured" space were live objects, the Full GC did not free up much space in "tenured" (only a single 1MB dead object left from my application). So only 12% of 10944K objects in "eden" were promoted to "tenured" space.
• At the end of GC, heap usage was 88%*10944K in "eden + 0K in "from" + 27316K in "tenured", about 36M, which presented 32M for my application and 4M for JVM.

The seventh GC happened as a Full GC after 2 iterations, because "eden" space could only take 2 more new 1MB objects from my application.

```34   40566784   2103912   38462872
35   40566784   1041176   39525608
[debug][gc,heap] GC(6) Heap before GC invocations=5 (full 2):
def new generation   total 12288K, used 12287K [...
[debug][gc,heap] GC(6)   eden space 10944K, 100% used [...
[debug][gc,heap] GC(6)   from space 1344K,  99% used [...
[debug][gc,heap] GC(6)   to   space 1344K,   0% used [...
[debug][gc,heap] GC(6)  tenured generation   total 27328K, used 27319K [...
[debug][gc,heap] GC(6)    the space 27328K,  99% used [...

[info ][gc,heap] GC(6) DefNew: 12287K->10301K(12288K)
[info ][gc,heap] GC(6) Tenured: 27319K->27160K(27328K)
[info ][gc     ] GC(6) Pause Full (Allocation Failure) 38M->36M(38M) 60.615ms

[debug][gc,heap] GC(6) Heap after GC invocations=6 (full 3):
def new generation   total 12288K, used 10301K [...
[debug][gc,heap] GC(6)   eden space 10944K,  94% used [...
[debug][gc,heap] GC(6)   from space 1344K,   0% used [...
[debug][gc,heap] GC(6)   to   space 1344K,   0% used [...
[debug][gc,heap] GC(6)  tenured generation   total 27328K, used 27160K [...
[debug][gc,heap] GC(6)    the space 27328K,  99% used [...
```

Notes on the above GC:

• This GC was triggered by 100% usage of "eden" space. It should be a Young GC. But there is no room left to promote live objects from "young" generation to "tenured" generation, a Full GC was executed.
• The messages in the "Heap before GC" section showed that some new objects was directly allocated in the "from" space, taking 99% of its 1344K space. This is different than my expectation.
• At the end of GC, heap usage was 94%*10944K in "eden + 0K in "from" + 27160K in "tenured", about 36M, which presented 32M for my application and 4M for JVM.

From this point on, the Serial collector continued perform Full GC every 2 to 4 iterations.

Conclusion:

• GCs are triggered when "eden" space is full.
• If the garbage collector is doing mark-sweep process on "young" generation only, it is considered as a simple Young generation GC, also called minor GC.
• If the garbage collector is doing mark-sweep process on both "young" and "tenured" generations, it is considered as a full GC.
• If heap size is tight, just enough to hold all live objects, the garbage collector will perform GC very frequently.
• When the garbage collector is promoting live objects from "eden" space to "from" space, it may decide to promote them directly to "tenured" space, if objects are too big to fit in "from" space. "from" space will be left empty and not used.

Table of Contents