How G1 Garbage Collector work in Java

Perspective Mentor
12 min readSep 10, 2023

--

G1 Garbage collector takes a new approach of garbage collection which will make it stand out in other Garbage Collection algorithms in java.

Introduction

The G1 (Garbage-First) garbage collector is a garbage collection algorithm introduced in Java as an alternative to the older Parallel and CMS (Concurrent Mark-Sweep) garbage collectors. It is designed to provide better predictability in terms of pause times for applications while still achieving good overall throughput. Here’s a detailed overview of how the G1 garbage collector works.

Heap Division:

The heap is divided into multiple regions, with each region being a contiguous block of memory. These regions are typically of different sizes, and they serve different purposes. There are three main types of regions in G1:

  • Eden: This is where newly created objects are allocated.
  • Survivor: There are typically two Survivor regions (S0 and S1), and they are used to hold objects that have survived one or more garbage collection cycles.
  • Old Generation: This region is used to hold long-lived objects that have survived multiple garbage collection cycles.
Multiple regions in Heap of different sizes.

Each block size will vary from 1 MB to 32 MB.
The total number of blocks will be approximately 2048 in number (or less based on JVM memory allocated).
Total number of blocks does not exceed 2048 blocks.

For Example if we have allocate 8GB memory to JVM it will create around 2000 blocks of size 3-4MB each. Each block will be of Eden, Survivor or Old Generation type. There will be some unallocated space kept.

It number of Eden, Survivor and Old generation blocks will be different. The New Generation (Eden + Survivor) will have minimum 5% to maximum 60% of JVM allocated memory. This gets decided based on different types of applications. Hence it is not recommended to allocate any fixed value to New Generation area in case of G1GC.

What will happen if we need to create a object that is larger than block size? This is handled differently we will discuss about it at end.

Initial Mark:

G1 starts with an initial marking phase. During this phase, it identifies the live objects in the old generation and marks them as such. This phase is done concurrently with the application threads, so it has minimal impact on application performance.

Concurrent Marking:

After the initial mark, G1 performs a concurrent marking phase to identify more live objects in all regions of the heap. This phase runs concurrently with the application threads, allowing the application to continue executing.

Remark:

Once concurrent marking is completed, G1 performs a remark phase to identify any objects that may have been modified since the initial marking. This ensures accuracy in determining live objects. This phase may cause a brief pause in application execution.

Concurrent Cleanup:

After the remark phase, G1 performs concurrent cleanup, which involves reclaiming memory from regions that are no longer in use. This is done concurrently with the application threads.

Evacuation:

G1 uses a process called “evacuation” to move live objects from one region to another. It selects regions with the most garbage (hence the name “Garbage-First”) and prioritizes them for evacuation. The goal is to empty regions with a lot of garbage to minimize fragmentation and improve overall heap utilization.

Mixed Garbage Collection:

G1 uses a concept called “mixed garbage collection” to perform garbage collection on both the young generation (Eden and Survivor regions) and the old generation. This allows G1 to achieve better overall heap utilization and avoid long pause times associated with full garbage collections.

Collection Set:

G1 maintains a list of regions called the “collection set,” which contains regions that are candidates for garbage collection. These regions are selected based on their garbage content and are collected during a garbage collection cycle.

Pause Time Target:

G1 aims to meet a user-specified pause time target. It dynamically adjusts its behavior to achieve this target by controlling the size of the collection set and other parameters.

Repeat Cycle:

G1 continuously repeats the garbage collection cycle, adjusting its priorities based on the state of the heap and the desired pause time targets.

Implementation

We will write a small program and run it with G1GC algorithm. We are creating a class A. In class A we are creating Double list of size 100. In main G1GCVerification class we are creating objects of class A repetitively with a sleep of 1 seconds.

import java.util.ArrayList;
import java.util.List;

public class G1GCVerification {

public static void main(String[] args) {
createRecurringObjects();
}

private static void createRecurringObjects() {
for (int i=0 ; i< 10000; i++) {
for(int j=0; j<100000; j++){
A a = new A();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

class A {
List<Double> list = new ArrayList<>(100);
}

jcmd Command:

This command is available after java 9. Following is the output of jcmd command. (Note: To capture jcmd output, this program is executed from IntelliJ IDE and is running on less memory.)

>java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment Corretto-17.0.5.8.1 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.5.8.1 (build 17.0.5+8-LTS, mixed mode, sharing)

>jps
13296 Jps
6912 GradleDaemon
8432
12572 G1GCVerification
7884 GradleDaemon

>jcmd 12572 jcmd 12572 VM.info

jcmd command prints huge output. will discuss some inportent portions of it.

Heap:
garbage-first heap total 260096K, used 34351K [0x0000000702400000, 0x0000000800000000)
region size 2048K, 18 young (36864K), 1 survivors (2048K)
Metaspace used 141K, committed 384K, reserved 1056768K
class space used 4K, committed 128K, reserved 1048576K

Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, OA=open archive, CA=closed archive, TAMS=top-at-mark-start (previous, next)
| 0|0x0000000702400000, 0x000000070248ac00, 0x0000000702600000| 27%| O| |TAMS 0x0000000702400000, 0x0000000702400000| Untracked
| 1|0x0000000702600000, 0x0000000702600000, 0x0000000702800000| 0%| F| |TAMS 0x0000000702600000, 0x0000000702600000| Untracked
| 2|0x0000000702800000, 0x0000000702800000, 0x0000000702a00000| 0%| F| |TAMS 0x0000000702800000, 0x0000000702800000| Untracked
| 3|0x0000000702a00000, 0x0000000702a00000, 0x0000000702c00000| 0%| F| |TAMS 0x0000000702a00000, 0x0000000702a00000| Untracked
| 4|0x0000000702c00000, 0x0000000702c00000, 0x0000000702e00000| 0%| F| |TAMS 0x0000000702c00000, 0x0000000702c00000| Untracked
| 5|0x0000000702e00000, 0x0000000702e00000, 0x0000000703000000| 0%| F| |TAMS 0x0000000702e00000, 0x0000000702e00000| Untracked
| 6|0x0000000703000000, 0x0000000703000000, 0x0000000703200000| 0%| F| |TAMS 0x0000000703000000, 0x0000000703000000| Untracked
| 7|0x0000000703200000, 0x0000000703200000, 0x0000000703400000| 0%| F| |TAMS 0x0000000703200000, 0x0000000703200000| Untracked
| 8|0x0000000703400000, 0x0000000703400000, 0x0000000703600000| 0%| F| |TAMS 0x0000000703400000, 0x0000000703400000| Untracked
| 9|0x0000000703600000, 0x0000000703600000, 0x0000000703800000| 0%| F| |TAMS 0x0000000703600000, 0x0000000703600000| Untracked
| 10|0x0000000703800000, 0x0000000703800000, 0x0000000703a00000| 0%| F| |TAMS 0x0000000703800000, 0x0000000703800000| Untracked
| 11|0x0000000703a00000, 0x0000000703a00000, 0x0000000703c00000| 0%| F| |TAMS 0x0000000703a00000, 0x0000000703a00000| Untracked
| 12|0x0000000703c00000, 0x0000000703c00000, 0x0000000703e00000| 0%| F| |TAMS 0x0000000703c00000, 0x0000000703c00000| Untracked
| 13|0x0000000703e00000, 0x0000000703e00000, 0x0000000704000000| 0%| F| |TAMS 0x0000000703e00000, 0x0000000703e00000| Untracked
| 14|0x0000000704000000, 0x0000000704000000, 0x0000000704200000| 0%| F| |TAMS 0x0000000704000000, 0x0000000704000000| Untracked
| 15|0x0000000704200000, 0x0000000704200000, 0x0000000704400000| 0%| F| |TAMS 0x0000000704200000, 0x0000000704200000| Untracked
| 16|0x0000000704400000, 0x0000000704400000, 0x0000000704600000| 0%| F| |TAMS 0x0000000704400000, 0x0000000704400000| Untracked
| 17|0x0000000704600000, 0x0000000704600000, 0x0000000704800000| 0%| F| |TAMS 0x0000000704600000, 0x0000000704600000| Untracked
| 18|0x0000000704800000, 0x0000000704800000, 0x0000000704a00000| 0%| F| |TAMS 0x0000000704800000, 0x0000000704800000| Untracked
| 19|0x0000000704a00000, 0x0000000704a00000, 0x0000000704c00000| 0%| F| |TAMS 0x0000000704a00000, 0x0000000704a00000| Untracked
| 20|0x0000000704c00000, 0x0000000704c00000, 0x0000000704e00000| 0%| F| |TAMS 0x0000000704c00000, 0x0000000704c00000| Untracked
| 21|0x0000000704e00000, 0x0000000704e00000, 0x0000000705000000| 0%| F| |TAMS 0x0000000704e00000, 0x0000000704e00000| Untracked
| 22|0x0000000705000000, 0x0000000705000000, 0x0000000705200000| 0%| F| |TAMS 0x0000000705000000, 0x0000000705000000| Untracked
| 23|0x0000000705200000, 0x0000000705200000, 0x0000000705400000| 0%| F| |TAMS 0x0000000705200000, 0x0000000705200000| Untracked
| 24|0x0000000705400000, 0x0000000705400000, 0x0000000705600000| 0%| F| |TAMS 0x0000000705400000, 0x0000000705400000| Untracked
| 25|0x0000000705600000, 0x0000000705600000, 0x0000000705800000| 0%| F| |TAMS 0x0000000705600000, 0x0000000705600000| Untracked
| 26|0x0000000705800000, 0x0000000705800000, 0x0000000705a00000| 0%| F| |TAMS 0x0000000705800000, 0x0000000705800000| Untracked
| 27|0x0000000705a00000, 0x0000000705a00000, 0x0000000705c00000| 0%| F| |TAMS 0x0000000705a00000, 0x0000000705a00000| Untracked
| 28|0x0000000705c00000, 0x0000000705c00000, 0x0000000705e00000| 0%| F| |TAMS 0x0000000705c00000, 0x0000000705c00000| Untracked
| 29|0x0000000705e00000, 0x0000000705e00000, 0x0000000706000000| 0%| F| |TAMS 0x0000000705e00000, 0x0000000705e00000| Untracked
| 30|0x0000000706000000, 0x0000000706000000, 0x0000000706200000| 0%| F| |TAMS 0x0000000706000000, 0x0000000706000000| Untracked
| 31|0x0000000706200000, 0x0000000706200000, 0x0000000706400000| 0%| F| |TAMS 0x0000000706200000, 0x0000000706200000| Untracked
| 32|0x0000000706400000, 0x0000000706400000, 0x0000000706600000| 0%| F| |TAMS 0x0000000706400000, 0x0000000706400000| Untracked
| 33|0x0000000706600000, 0x0000000706600000, 0x0000000706800000| 0%| F| |TAMS 0x0000000706600000, 0x0000000706600000| Untracked
| 34|0x0000000706800000, 0x0000000706800000, 0x0000000706a00000| 0%| F| |TAMS 0x0000000706800000, 0x0000000706800000| Untracked
| 35|0x0000000706a00000, 0x0000000706a00000, 0x0000000706c00000| 0%| F| |TAMS 0x0000000706a00000, 0x0000000706a00000| Untracked
| 36|0x0000000706c00000, 0x0000000706c00000, 0x0000000706e00000| 0%| F| |TAMS 0x0000000706c00000, 0x0000000706c00000| Untracked
| 37|0x0000000706e00000, 0x0000000706e00000, 0x0000000707000000| 0%| F| |TAMS 0x0000000706e00000, 0x0000000706e00000| Untracked
| 38|0x0000000707000000, 0x0000000707000000, 0x0000000707200000| 0%| F| |TAMS 0x0000000707000000, 0x0000000707000000| Untracked
| 39|0x0000000707200000, 0x0000000707200000, 0x0000000707400000| 0%| F| |TAMS 0x0000000707200000, 0x0000000707200000| Untracked
| 40|0x0000000707400000, 0x0000000707400000, 0x0000000707600000| 0%| F| |TAMS 0x0000000707400000, 0x0000000707400000| Untracked
| 41|0x0000000707600000, 0x0000000707600000, 0x0000000707800000| 0%| F| |TAMS 0x0000000707600000, 0x0000000707600000| Untracked
| 42|0x0000000707800000, 0x0000000707800000, 0x0000000707a00000| 0%| F| |TAMS 0x0000000707800000, 0x0000000707800000| Untracked
| 43|0x0000000707a00000, 0x0000000707a00000, 0x0000000707c00000| 0%| F| |TAMS 0x0000000707a00000, 0x0000000707a00000| Untracked
| 44|0x0000000707c00000, 0x0000000707c00000, 0x0000000707e00000| 0%| F| |TAMS 0x0000000707c00000, 0x0000000707c00000| Untracked
| 45|0x0000000707e00000, 0x0000000707e00000, 0x0000000708000000| 0%| F| |TAMS 0x0000000707e00000, 0x0000000707e00000| Untracked
| 46|0x0000000708000000, 0x0000000708000000, 0x0000000708200000| 0%| F| |TAMS 0x0000000708000000, 0x0000000708000000| Untracked
| 47|0x0000000708200000, 0x0000000708200000, 0x0000000708400000| 0%| F| |TAMS 0x0000000708200000, 0x0000000708200000| Untracked
| 48|0x0000000708400000, 0x0000000708400000, 0x0000000708600000| 0%| F| |TAMS 0x0000000708400000, 0x0000000708400000| Untracked
| 49|0x0000000708600000, 0x0000000708600000, 0x0000000708800000| 0%| F| |TAMS 0x0000000708600000, 0x0000000708600000| Untracked
| 50|0x0000000708800000, 0x0000000708800000, 0x0000000708a00000| 0%| F| |TAMS 0x0000000708800000, 0x0000000708800000| Untracked
| 51|0x0000000708a00000, 0x0000000708a00810, 0x0000000708c00000| 0%| S|CS|TAMS 0x0000000708a00000, 0x0000000708a00000| Complete
| 52|0x0000000708c00000, 0x0000000708c00000, 0x0000000708e00000| 0%| F| |TAMS 0x0000000708c00000, 0x0000000708c00000| Untracked
| 53|0x0000000708e00000, 0x0000000708e00000, 0x0000000709000000| 0%| F| |TAMS 0x0000000708e00000, 0x0000000708e00000| Untracked
| 54|0x0000000709000000, 0x0000000709000000, 0x0000000709200000| 0%| F| |TAMS 0x0000000709000000, 0x0000000709000000| Untracked
| 55|0x0000000709200000, 0x0000000709200000, 0x0000000709400000| 0%| F| |TAMS 0x0000000709200000, 0x0000000709200000| Untracked
| 56|0x0000000709400000, 0x0000000709400000, 0x0000000709600000| 0%| F| |TAMS 0x0000000709400000, 0x0000000709400000| Untracked
| 57|0x0000000709600000, 0x0000000709600000, 0x0000000709800000| 0%| F| |TAMS 0x0000000709600000, 0x0000000709600000| Untracked
| 58|0x0000000709800000, 0x0000000709800000, 0x0000000709a00000| 0%| F| |TAMS 0x0000000709800000, 0x0000000709800000| Untracked
| 59|0x0000000709a00000, 0x0000000709a00000, 0x0000000709c00000| 0%| F| |TAMS 0x0000000709a00000, 0x0000000709a00000| Untracked
| 60|0x0000000709c00000, 0x0000000709c00000, 0x0000000709e00000| 0%| F| |TAMS 0x0000000709c00000, 0x0000000709c00000| Untracked
| 61|0x0000000709e00000, 0x0000000709e00000, 0x000000070a000000| 0%| F| |TAMS 0x0000000709e00000, 0x0000000709e00000| Untracked
| 62|0x000000070a000000, 0x000000070a000000, 0x000000070a200000| 0%| F| |TAMS 0x000000070a000000, 0x000000070a000000| Untracked
| 63|0x000000070a200000, 0x000000070a200000, 0x000000070a400000| 0%| F| |TAMS 0x000000070a200000, 0x000000070a200000| Untracked
| 64|0x000000070a400000, 0x000000070a400000, 0x000000070a600000| 0%| F| |TAMS 0x000000070a400000, 0x000000070a400000| Untracked
| 65|0x000000070a600000, 0x000000070a600000, 0x000000070a800000| 0%| F| |TAMS 0x000000070a600000, 0x000000070a600000| Untracked
| 66|0x000000070a800000, 0x000000070a800000, 0x000000070aa00000| 0%| F| |TAMS 0x000000070a800000, 0x000000070a800000| Untracked
| 67|0x000000070aa00000, 0x000000070aa00000, 0x000000070ac00000| 0%| F| |TAMS 0x000000070aa00000, 0x000000070aa00000| Untracked
| 68|0x000000070ac00000, 0x000000070ac00000, 0x000000070ae00000| 0%| F| |TAMS 0x000000070ac00000, 0x000000070ac00000| Untracked
| 69|0x000000070ae00000, 0x000000070ae00000, 0x000000070b000000| 0%| F| |TAMS 0x000000070ae00000, 0x000000070ae00000| Untracked
| 70|0x000000070b000000, 0x000000070b000000, 0x000000070b200000| 0%| F| |TAMS 0x000000070b000000, 0x000000070b000000| Untracked
| 71|0x000000070b200000, 0x000000070b200000, 0x000000070b400000| 0%| F| |TAMS 0x000000070b200000, 0x000000070b200000| Untracked
| 72|0x000000070b400000, 0x000000070b400000, 0x000000070b600000| 0%| F| |TAMS 0x000000070b400000, 0x000000070b400000| Untracked
| 73|0x000000070b600000, 0x000000070b600000, 0x000000070b800000| 0%| F| |TAMS 0x000000070b600000, 0x000000070b600000| Untracked
| 74|0x000000070b800000, 0x000000070b800000, 0x000000070ba00000| 0%| F| |TAMS 0x000000070b800000, 0x000000070b800000| Untracked
| 75|0x000000070ba00000, 0x000000070ba00000, 0x000000070bc00000| 0%| F| |TAMS 0x000000070ba00000, 0x000000070ba00000| Untracked
| 76|0x000000070bc00000, 0x000000070bc00000, 0x000000070be00000| 0%| F| |TAMS 0x000000070bc00000, 0x000000070bc00000| Untracked
| 77|0x000000070be00000, 0x000000070be00000, 0x000000070c000000| 0%| F| |TAMS 0x000000070be00000, 0x000000070be00000| Untracked
| 78|0x000000070c000000, 0x000000070c000000, 0x000000070c200000| 0%| F| |TAMS 0x000000070c000000, 0x000000070c000000| Untracked
| 79|0x000000070c200000, 0x000000070c200000, 0x000000070c400000| 0%| F| |TAMS 0x000000070c200000, 0x000000070c200000| Untracked
| 80|0x000000070c400000, 0x000000070c400000, 0x000000070c600000| 0%| F| |TAMS 0x000000070c400000, 0x000000070c400000| Untracked
| 81|0x000000070c600000, 0x000000070c600000, 0x000000070c800000| 0%| F| |TAMS 0x000000070c600000, 0x000000070c600000| Untracked
| 82|0x000000070c800000, 0x000000070c800000, 0x000000070ca00000| 0%| F| |TAMS 0x000000070c800000, 0x000000070c800000| Untracked
| 83|0x000000070ca00000, 0x000000070ca00000, 0x000000070cc00000| 0%| F| |TAMS 0x000000070ca00000, 0x000000070ca00000| Untracked
| 84|0x000000070cc00000, 0x000000070cc00000, 0x000000070ce00000| 0%| F| |TAMS 0x000000070cc00000, 0x000000070cc00000| Untracked
| 85|0x000000070ce00000, 0x000000070ce00000, 0x000000070d000000| 0%| F| |TAMS 0x000000070ce00000, 0x000000070ce00000| Untracked
| 86|0x000000070d000000, 0x000000070d000000, 0x000000070d200000| 0%| F| |TAMS 0x000000070d000000, 0x000000070d000000| Untracked
| 87|0x000000070d200000, 0x000000070d200000, 0x000000070d400000| 0%| F| |TAMS 0x000000070d200000, 0x000000070d200000| Untracked
| 88|0x000000070d400000, 0x000000070d400000, 0x000000070d600000| 0%| F| |TAMS 0x000000070d400000, 0x000000070d400000| Untracked
| 89|0x000000070d600000, 0x000000070d600000, 0x000000070d800000| 0%| F| |TAMS 0x000000070d600000, 0x000000070d600000| Untracked
| 90|0x000000070d800000, 0x000000070d800000, 0x000000070da00000| 0%| F| |TAMS 0x000000070d800000, 0x000000070d800000| Untracked
| 91|0x000000070da00000, 0x000000070da00000, 0x000000070dc00000| 0%| F| |TAMS 0x000000070da00000, 0x000000070da00000| Untracked
| 92|0x000000070dc00000, 0x000000070dc00000, 0x000000070de00000| 0%| F| |TAMS 0x000000070dc00000, 0x000000070dc00000| Untracked
| 93|0x000000070de00000, 0x000000070de00000, 0x000000070e000000| 0%| F| |TAMS 0x000000070de00000, 0x000000070de00000| Untracked
| 94|0x000000070e000000, 0x000000070e000000, 0x000000070e200000| 0%| F| |TAMS 0x000000070e000000, 0x000000070e000000| Untracked
| 95|0x000000070e200000, 0x000000070e200000, 0x000000070e400000| 0%| F| |TAMS 0x000000070e200000, 0x000000070e200000| Untracked
| 96|0x000000070e400000, 0x000000070e400000, 0x000000070e600000| 0%| F| |TAMS 0x000000070e400000, 0x000000070e400000| Untracked
| 97|0x000000070e600000, 0x000000070e600000, 0x000000070e800000| 0%| F| |TAMS 0x000000070e600000, 0x000000070e600000| Untracked
| 98|0x000000070e800000, 0x000000070e800000, 0x000000070ea00000| 0%| F| |TAMS 0x000000070e800000, 0x000000070e800000| Untracked
| 99|0x000000070ea00000, 0x000000070ea00000, 0x000000070ec00000| 0%| F| |TAMS 0x000000070ea00000, 0x000000070ea00000| Untracked
| 100|0x000000070ec00000, 0x000000070ec00000, 0x000000070ee00000| 0%| F| |TAMS 0x000000070ec00000, 0x000000070ec00000| Untracked
| 101|0x000000070ee00000, 0x000000070ee00000, 0x000000070f000000| 0%| F| |TAMS 0x000000070ee00000, 0x000000070ee00000| Untracked
| 102|0x000000070f000000, 0x000000070f000000, 0x000000070f200000| 0%| F| |TAMS 0x000000070f000000, 0x000000070f000000| Untracked
| 103|0x000000070f200000, 0x000000070f200000, 0x000000070f400000| 0%| F| |TAMS 0x000000070f200000, 0x000000070f200000| Untracked
| 104|0x000000070f400000, 0x000000070f400000, 0x000000070f600000| 0%| F| |TAMS 0x000000070f400000, 0x000000070f400000| Untracked
| 105|0x000000070f600000, 0x000000070f600000, 0x000000070f800000| 0%| F| |TAMS 0x000000070f600000, 0x000000070f600000| Untracked
| 106|0x000000070f800000, 0x000000070f800000, 0x000000070fa00000| 0%| F| |TAMS 0x000000070f800000, 0x000000070f800000| Untracked
| 107|0x000000070fa00000, 0x000000070fa00000, 0x000000070fc00000| 0%| F| |TAMS 0x000000070fa00000, 0x000000070fa00000| Untracked
| 108|0x000000070fc00000, 0x000000070fc00000, 0x000000070fe00000| 0%| F| |TAMS 0x000000070fc00000, 0x000000070fc00000| Untracked
| 109|0x000000070fe00000, 0x000000070fe00000, 0x0000000710000000| 0%| F| |TAMS 0x000000070fe00000, 0x000000070fe00000| Untracked
| 110|0x0000000710000000, 0x0000000710100800, 0x0000000710200000| 50%| E| |TAMS 0x0000000710000000, 0x0000000710000000| Complete
| 111|0x0000000710200000, 0x0000000710400000, 0x0000000710400000|100%| E|CS|TAMS 0x0000000710200000, 0x0000000710200000| Complete
| 112|0x0000000710400000, 0x0000000710600000, 0x0000000710600000|100%| E|CS|TAMS 0x0000000710400000, 0x0000000710400000| Complete
| 113|0x0000000710600000, 0x0000000710800000, 0x0000000710800000|100%| E|CS|TAMS 0x0000000710600000, 0x0000000710600000| Complete
| 114|0x0000000710800000, 0x0000000710a00000, 0x0000000710a00000|100%| E|CS|TAMS 0x0000000710800000, 0x0000000710800000| Complete
| 115|0x0000000710a00000, 0x0000000710c00000, 0x0000000710c00000|100%| E|CS|TAMS 0x0000000710a00000, 0x0000000710a00000| Complete
| 116|0x0000000710c00000, 0x0000000710e00000, 0x0000000710e00000|100%| E|CS|TAMS 0x0000000710c00000, 0x0000000710c00000| Complete
| 117|0x0000000710e00000, 0x0000000711000000, 0x0000000711000000|100%| E|CS|TAMS 0x0000000710e00000, 0x0000000710e00000| Complete
| 118|0x0000000711000000, 0x0000000711200000, 0x0000000711200000|100%| E|CS|TAMS 0x0000000711000000, 0x0000000711000000| Complete
| 119|0x0000000711200000, 0x0000000711400000, 0x0000000711400000|100%| E|CS|TAMS 0x0000000711200000, 0x0000000711200000| Complete
| 120|0x0000000711400000, 0x0000000711600000, 0x0000000711600000|100%| E|CS|TAMS 0x0000000711400000, 0x0000000711400000| Complete
| 121|0x0000000711600000, 0x0000000711800000, 0x0000000711800000|100%| E|CS|TAMS 0x0000000711600000, 0x0000000711600000| Complete
| 122|0x0000000711800000, 0x0000000711a00000, 0x0000000711a00000|100%| E|CS|TAMS 0x0000000711800000, 0x0000000711800000| Complete
| 123|0x0000000711a00000, 0x0000000711c00000, 0x0000000711c00000|100%| E|CS|TAMS 0x0000000711a00000, 0x0000000711a00000| Complete
| 124|0x0000000711c00000, 0x0000000711e00000, 0x0000000711e00000|100%| E|CS|TAMS 0x0000000711c00000, 0x0000000711c00000| Complete
| 125|0x0000000711e00000, 0x0000000712000000, 0x0000000712000000|100%| E|CS|TAMS 0x0000000711e00000, 0x0000000711e00000| Complete
| 126|0x0000000712000000, 0x0000000712200000, 0x0000000712200000|100%| E|CS|TAMS 0x0000000712000000, 0x0000000712000000| Complete

Here we can see following points clearly in output.

Total size is — total 260096K
GC Algorithm — Garbage First
Region Size is — region size 2048K
Total no of Regions — 126
Total Eden Region — 18
Total Survivor Regions — 1
Lot of them are Free that can be used for Old Generation or if we have humongous object section. (since we have most of objects short lived).

As we are continuously creating objects we can see eden and survivors regions are filled and and are part of Collection Set. Whatever regions are marked or added in Collection Set will be considered for next GC cycle.

Abbreviations of labels —
E=young(eden),
S=young(survivor),
O=old,
HS=humongous(starts),
HC=humongous(continues),
CS=collection set,
F=free,
OA=open archive,
CA=closed archive,
TAMS=top-at-mark-start

Command line Options:

Run below commands to compile and run the code.

javac MemoryVerification.java
java -Xms1g -Xmx1g -XX:+UseG1GC G1GCVerification

Here we are passing -XX:+UseG1GC so that JVM can use G1GC as a algorithm while running program.

Analyzing Memory using jstat and jconsole utilities. These are by default available with JDK.

jstat Command:

We will be using jstat utility that comes by default with java. Run jps command to list all java processes running on system. Look for process id of java process with name G1GCVerification.

Run below jstat command. (2000 at last will keep on running this command every 2000 milliseconds i.e every 2 seconds)

jstat -gc <pid-of-memory-verification-program> 2000
output of jstat command

Here it shows combined/added memory of all Eden, Survivor 0, Survivor 1 and Old Generation blocks spaces. We can see EU (Eden utilization) increasing consistently.

Jconsole command:

Run below jconsole command.

jconsole <pid-of-memory-verification-program>

After running jconsole command it will open Java Monitoring UI in windows.

jconsole command output

Here we can see current program is using G1GC and 1GB memory is allocated to JVM as configured.

Now will discuss about how to deal with objects that are larger than block size in G1GC.

Humongous Objects

In G1GC, any object that is more than half a region size is considered a “Humongous object”.

  • Humongous objects are too big to fit into the normal memory sections G1GC uses for regular objects.
  • So, G1GC handles Humongous Objects differently.
  • Instead of splitting them into smaller pieces, G1GC keeps Humongous Objects together in a special memory area.
  • Just like regular objects, Humongous Objects can become unnecessary or “garbage” over time.
  • G1GC checks them too during garbage collection to see if they’re still needed. If a Humongous Object is no longer needed, G1GC can free up its memory.
  • G1GC deals with Humongous Objects carefully, keeping them in a separate area to avoid fragmentation (memory wastage) and ensuring garbage collection for them is as efficient as possible.
  • In-order to reduce copying overhead, the Humongous objects are not included in any evacuation pause. A full garbage collection cycle compacts Humongous objects in place.

G1GC (Garbage-First Garbage Collector) properties

Below is the list of properties of G1GC along with its usage and default value.

XX:+UseG1GC

  • Description: Enables G1GC as the garbage collector.
  • Default Value: Not set (must be explicitly enabled).

XX:MaxGCPauseMillis

  • Description: Sets the maximum target pause time for G1GC in milliseconds.
  • Default Value: 200 milliseconds.

XX:G1HeapRegionSize

  • Description: Defines the size of individual G1GC regions.
  • Default Value: Automatically calculated based on heap size.

XX:InitiatingHeapOccupancyPercent

  • Description: Controls when G1GC starts its garbage collection cycle based on heap occupancy.
  • Default Value: 45%.

XX:ParallelGCThreads

  • Description: Sets the number of parallel threads used by G1GC.
  • Default Value: Number of available processors.

XX:ConcGCThreads

  • Description: Specifies the number of concurrent GC threads for certain tasks.
  • Default Value: Number of available processors.

XX:G1ReservePercent

  • Description: Reserves a percentage of heap memory for GC overhead.
  • Default Value: 10% of the heap.

XX:G1HeapWastePercent

  • Description: Controls the percentage of memory that can be wasted in a region before G1 considers it reclaimable.
  • Default Value: 5%.

XX:G1MixedGCLiveThresholdPercent

  • Description: Sets the percentage of live data in a region required to consider it for mixed garbage collection.
  • Default Value: 65%.

XX:MaxTenuringThreshold

  • Description: Sets the maximum tenuring threshold for objects in the Young generation.
  • Default Value: 15.

Conclusion:

G1GC algorithm takes entirely different approach and is best suited for applications with large JVM memory. Please analyze JVM metrics of your running enterprise application and understand how G1GC is cleaning up memory. Happy Learning!

If you are interested in reading on how CMS (Concurrent Mark and Sweep) works please read article here.

--

--

Perspective Mentor

Solutions Architect skilled in Java, Spring, Kafka, Elasticsearch, Vault, Docker, Kubernetes, AI, AWS, GCP & Security. Educator @ https://perspectivementor.com