Hey everyone, in this blog, we will look at Garbage Collection in the JVM specifically how G1 Garbage Collector (G1GC) works. We will begin with the basic terms that we need to be aware of the working of garbage collection and then we will proceed to see how G1GC collects the garbage.
In Java, the programmer is not responsible for freeing the memory (as is done in C using malloc and free). The Java Garbage Collector is responsible for freeing the memory.
- Footprint: Amount of memory required by the GC algorithm.
- Throughput: Time that the program runs vs when the GC runs. Runtime for the program. Number of transactions per second.
- Latency: Amount of time code pauses for GC. Maximum time of a transaction.
- Eden Region: Forms part of the Young Generation
- Survivor Region: Also forms part of the Young Generation
- Young Generation: This is an area in the heap that comprises the Eden and Survivor Regions. This is the first region where newly created objects in the heap are placed
- Old Generation: This is the area of the heap where old heap objects are present.
- All the objects will be allocated to a memory area called the heap. These objects are laid out in the memory along with the respective field and can contain references to other objects and Booleans and other values.
- As we start to fill up more objects the heap area is filled eventually.
- Now the Garbage collector will pause the application and will see which objects are currently in use by the program. The GC will find out which objects are in use and will do so by starting from “Roots”. To figure out which objects are “live” in the heap the GC will pause the Java application, scan the thread stacks, and find references pointing out to objects. These objects are considered “live”. Then it iterates over each object, in turn, to find out references for other objects.
- Once we have found all the “live” objects we compact them to one area of the heap and have a contiguous free area in the heap area for more allocation.
Image Source: Oracle
Working of G1GC
- G1 uses generational region-based memory management. The G1GC divides heap into multiple memory regions. The region size will depend on the heap size. Eg: 2 MB for 4 GB heap means that 2048 regions.
- JVM allocates new objects are into the “Eden regions” (E). A “young collection” (YC) happens after the JVM allocates a number of “Eden regions” . This will copy live objects from the Eden region to the survivor regions.
- If the object survives multiple young collections, then the JVM compacts and copies them into an old region (O).
- After a while, the heap fills up with Eden, Survivor and Old regions with live objects.
- Soon, G1GC starts a concurrent mark cycle (CMC) to find out in the old regions, which objects are in use, and which are not.
- G1GC and JVM ensures that it does not stop the Java application during the concurrent mark cycle.
- After G1GC completes the Concurrent Mark Cycle, it collects the Eden, survivor and old regions into “mixed collections” (MC). Live objects are compactly copied into Survivor and old regions.
- Then the G1GC collects the eligible objects from Eden, Survivor and old regions. When no more old regions are suitable for collection (i.e., they refer to too many live references and so it is not worth collecting them), then G1 will resume doing young collections.
- G1GC thus transitions between the following states. It starts off with doing Young Collections which will copy objects into survivor regions and promote them to old regions. After a while, as the heap is getting occupied a concurrent mark cycle will be started. The CMC runs concurrently with the application and young collections as well. Once the CMC finishes, G1 transitions into doing mixed collections. Once there are no longer suitable regions to collect, it will transition back to Young Collections, so the cycle repeats.
- So, the 3 states are – YC, YC + CM + MC. ‘
Image Source: Oracle
I hope you found this blog helpful. The intent is that everyone who works on a language that works on JVM, be it Java, Scala, or Kotlin. So whenever you are facing issues with heap memory in your JVM and you are debugging it I hope you will find this blog useful
Source: Official Oralce Docs