What is Garbage collection in Java?
In Java, the Garbage collector in the JVM(Java Virtual Machine) detects unused objects and destroys those objects. It keeps running in the background. Garbage collection is very helpful for programmers because they no need to care about the objects which are no longer in use.
Unlike in C, C++ where the programmer is solely responsible for the creation and deletion of objects. And the ignorance in the deletion of objects will result in Out Of Memory errors in C and C++.
Here, the garbage collector frees the heap memory by destroying even the unreachable objects.
How does Java Garbage Collection work?
Java Garbage Collection is an automatic process where it looks at the heap memory and identifies the objects in use and the ones which are not, thereby deleting the unused objects from the memory.
In other words, Java Garbage Collection tracks the live objects in the JVM and the other objects are considered garbage, which can be destroyed. Usually, when an object is no longer used, there is no explicit deletion so no memory is given back to the operating system.
Every time, when an object is used it is referenced by the JVM, which means it is treated as live by the JVM and it cannot be re-used again. So, if another object is created, they are simply added to the end of the heap.
An object is considered alive as long as it is referenced by the JVM. So, an unreferenced object, which is no longer reachable by the application code, will be removed by the garbage collector and the unused memory can be reclaimed.
Types of Garbage Collection Activities in Java
The two types of garbage collection activities in Java are as follows:
Minor or Incremental Garbage collection: Collecting garbage(unreachable objects) from the young generation's heap memory is called minor garbage collection.
Major or Full Garbage collection: A threshold has been set for the young generation object, and when the time comes, they are moved to the old generation, which is then collected by the garbage collector, called major garbage collection.
Garbage Collection roots
Garbage Collection roots are special objects for the Garbage collector. They are the starting point of the Garbage Collection process. The objects which are directly or indirectly referenced by Garbage Collection roots are not collected by the Garbage Collector.
Types of Garbage Collection roots in Java:
There are four types of Garbage Collection roots in Java, which are explained as follows:
Local Variables They are kept alive by a stack of thread which is not a real object virtual reference and is not visible. Local variables are garbage collection roots for all intents and purposes.
Article Java threads They are considered to be live objects and therefore they are Garbage Collection roots. These are important to the local variables.
Static variables They are referenced by their classes. Classes themselves can be garbage collected which will remove all the referenced static variables.
JNI References They are the java objects which was created by the native code as a part of the JNI call. The objects created here will not be known by the JVM whether they are being referenced or not so they are treated as special objects and they have a special form of Garbage Collection roots too.
Why is monitoring Garbage Collection important?
Garbage Collection impacts the performance of Java applications in many ways which are mostly unpredictable. Frequent Garbage collection activities can lead to a high CPU load and slow down the processing of applications.
Insufficient memory allocation and memory leaks in the Java application are the reasons behind the Garbage collection activity in Java. It is important to monitor the Garbage collection activity, as it may result in loading CPU resulting in poor application performance.
Types of Garbage Collectors:
The types of Garbage collectors in the JVM are as follows:
Serial GC
- This is designed for small applications running in single-threaded environments.
- All the garbage events are conducted in a single thread serially.
The JVM argument for the Serial Garbage collector is
-XX:+UseSerialGC
.
Parallel GC
- These are intended for medium-sized to large-sized applications.
- This is called a Throughput Collector and is also the default implementation of Garbage collection in JVM.
- In the young generation, multiple threads are used for minor garbage collection whereas, in the old generation, a single thread is used for major garbage collection.
The JVM argument for the Parallel Garbage collector is
-XX:+UseParallelGC
.
Parallel Old GC
- It is the same as the Parallel GC except for the fact that it uses multiple threads for both young and old generations.
The JVM argument for the Parallel Old Garbage collector is -XX:+UseParallelOldGC.
CMS(Concurrent Mark Sweep) GC
- For minor garbage collection, multiple threads are used by using the same algorithm in parallel.
- Like Parallel Old GC, the major garbage collection is multi-threaded.
The JVM argument for the Concurrent Mark Sweep GC is
-XX:+UseConcMarkSweepGC
.
G1(Garbage First) GC
- G1GC was designed for multi-threaded applications which have a large heap size available, say more than 4GB.
- It was intended as a replacement for Concurrent Mark Sweep GC.
- It is parallel and concurrent like CMS, but it works somewhat differently compared to the older garbage collectors.
The JVM argument for the Garbage First GC is
-XX:+UseG1GC
.
Epsilon Garabage Collector
- Epsilon is a do-nothing(no-op) garbage collector which handles memory allocation but does not implement any actual memory reclamation mechanism.
- It can be used in ultra-latency-sensitive applications where developers know exactly about the application memory footprint or even have completely garbage-free applications.
- The JVM argument for the Concurrent Mark Sweep GC is
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
.
Best Practices in Garbage Collection:
Here are some best practices to be followed in Garbage Collection. They are as follows:
The Garbage collection in Java is non-deterministic. It is impossible to predict when garbage collection occurs at run time but possible to run the garbage collector with the system.gc() or runtime.gc() methods.
Default settings are enough for small Java applications and they don’t need any kind of specific garbage collectors.
If the heap is too small or if there is a memory leak in the application, then the application may slow down and also has out of memory errors. So a monitoring tool like Java flight recorder or jstat must be used to monitor the heap usage.
Conclusion:
For many simple applications, Garbage collection is not necessarily needed. But for other kinds of applications, programmers should be able to understand the working of Garbage collection. Having a good understanding of Garbage collection along with following the best practices is very essential.