Whenever any Java program runs on the JVM, objects get created on the Heap and with time many such objects get accumulated. So to ensure memory availability to the running applications. JVM initiates Garbage Collection using the JVM Garbage Collector(GC), which is primarily a Daemon thread. GC then find these unused objects and destroy them to free up the Heap Space.
String s = new String(); s = null; // Note, now the String object is not reachable as its // referenced has been nulled
1. How Garbage Collector Works?
Garbage collector works on the principle of ‘Marking and Compacting’. In brief, it works as below:
Step 1: Marking
In the first image, the Garbage Collector identifies the used and unused sections of memory. Used memory sections are marked with color ‘Blue’.
Step 2: Deletion
In the second image, the used but dereferenced objects are marked(orange) in memory space and are then deleted, also references to the free space and the live objects are saved.
Step 3: Compaction
To improve the performance further, all the live objects are moved together, leaving only the empty space available for the next memory allocation.
2. Generational Garbage Collection
In any usual application, Generational GC is the most commonly adopted methodology. In this method, Heap is divided into the following generations(spaces):
This is the space where all the new objects are created and once it’s full to its threshold, GC runs and frees up the space taken by all the unreachable objects; this activity is called Minor GC. The remaining objects that are still being referenced and aged are moved to the old generation space.
All the long-lived objects that are moved from the young generation post ‘Minor GC’ are found here. GC process here in Old Generation is referred to as Major GC because the entire old generation is scanned to clean up and compact the utilized space further.
This space stores metadata such as classes and methods. Here classes that are no longer in use are garbage collected.
3. Types of Garbage Collector
As the Java evolved, Garbage Collectors also progressed to support changing factors such as application size, advanced processors, larger Heap memories, newer JDK e.t.c.
3.1 Serial GC
Simplest of all and designed specifically for Single Threaded Systems with small heap sizes. Though not counted as a reliable GC, it does the job for applications that do not have low pause time requirements.
To enable the Serial Collector use:
3.2 Parallel Collector:
Also called ‘Throughput Collector‘, uses multiple threads to perform the Garbage collection, which leads to better application throughput. JVM default choice for a host with multiple CPU is Parallel Collector only.
To enable the Parallel Collector use:
3.3 Concurrent Mark Sweep(CMS) Collector
Also referred to as ‘Low Pause collector’ as it tries to minimize the pauses due to Garbage Collection by doing most of the GC work in parallel to the application threads.
Note, Whenever fragmentation becomes a problem (as it doesn’t copy or compact the live objects), CMS collector tries to allocate a larger heap.
To enable the CMS Collector use:
3.4 G1 Garbage Collector
Though G1 Collector deserves to get an altogether separate topic, in brief:
G1 was introduced in JDK 7 and acts as a replacement to CMS Garbage collector, it is specifically designed for bigger heap sizes (>4GB) and is currently the default garbage collector for JDK 8 & 9.
Use cases for G1: Applications running today with either the CMS or the Parallel collector would greatly benefit switching to G1 if the application has one of the following traits.
- Way too long Garbage collection/compaction pauses (more than .5 or 1 second).
- If the rate of Object allocation or promotion to the next generation varies significantly.
- On an average basis, more than 50% of the heap is always occupied by live objects.
To enable the G1 Collector use: