Decoding the G1 garbage collector
Java garbage collection is the JVM’s memory management process. Java objects are created in a part of the memory that JVM calls the heap and when the heap grows eventually in the course of application lifecycle, a lot of these objects become obsolete.This is where garbage collector kicks in and cleans up the obsolete or garbage objects and frees up the memory.
G1 Garbage Collector
G1 garbage collector is a HotSpot low-pause generational collector. The first paper for G1 was published way back in 2004, and was available and supported with JDK 7u4 since 2012. G1 is meant to be a long term replacement for CMS(Concurrent mark and sweep) algorithm traditionally used as the primary GC in JVMs. The intent was to make it easy to tune with minimum configuration that would just make it work for most of the application.
G1 is a generational collector- which means it also divides the heap into generations (Young and Old) just like CMS. However, it adopts two algorithms for each generations.
Stop the world, Parallel and copying
Mostly concurrent marking(Similar to CMS) but then does Incremental Compaction piggybacked on Young Generation GC ( against the traditional sweeping in CMS) for reclaiming space.
G1 heap division
G1 primarily divides the heap into pretty small regions. It targets to divide the heap into 2048 regions. So for a bigger heap the regions are big sized where as for smaller heaps it would divide it into smaller sized regions. It then tags those regions into three divisions namely:
- Eden regions
- Survivor region
- Old region
- Humongous region : Contains only a single object (typically byte or a char) which has a size > 50 % of region size
Young Generation Garbage Collection
In the lifecycle of heap, JVM after dividing it into multiple regions, tags few of those regions as Eden, and starts filling them consecutively. After all the eden regions are filled up, it triggers the young generation garbage collector to start reclaiming space.
Now our application during it’s runtime, primarily does to things in terms of memory
- Allocate new objects
- Modify existing pointers
Tracking inter-generation references
It could very well be that an object in old region may point to an object in the eden region. For example a long lived map in old region, that starts referencing a new object just created in the eden region. G1, needs to track these inter-generation pointers while running it’s young generation algorithm.
Let’s take an example:
If you look at step