In this article we will learn about Garbage Collector(GC) and a little bit of Memory Leak.
Before we jump into the Garbage Collector we will first learn,
Memory leak is a type of resource leak that is unused and failed to deallocate or release from memory(RAM).
Memory leak occurs when GC could not release unused objects/resources. As a result it will reduce the amount of available memory and affect the performance of the application. However, it is not always the case where memory is full; it means there is a memory leak. Sometimes applications might be using a high amount of memory to perform heavy tasks.
Apart from garbage collector, it is the work of the developer to program in such a way that it releases unneeded resources/objects wherever it is required. Another good way to prevent memory leak is by minimizing the use of static members.
On rare occasions you would have faced java.lang.OutOfMemoryError during application runtime. This is because JVM could not able allocate memory(heap space) for that application. Java programmers, please note that calling a static method (System.gc()) manually will not guarantee that it will remove all unreachable objects. At the same time don’t forget garbage collector plays a major role in allocating/deallocating objects from heap memory.
GC is an automatic memory manager that manages the allocation and release of memory for an application.
Generally, whenever we open an application, the operating system will allocate a certain amount of memory for that application. GC will manage that memory throughout the application lifetime. It will run periodically with certain GC steps.
Initially, when an object is created in the heap, it will be a head node for the corresponding object and it will create a graph-like structure when the corresponding object holds the reference of others. Having that GC will follow three steps to perform garbage collection.
Mark: GC will walk through the object graph right from the beginning of the node and mark the objects that are reachable.
Sweep/Delete: It will ignore the objects that are marked as reachable and sweep off unreachable objects.
Compacting: The empty space left over after removing the unreachable objects will be defragmented by this step. This step will help to isolate memory that is being used and free.
The garbage collector traverses through the object graph in memory, starting from GC root to corresponding objects.
Basically, objects in the heap are divided into generations - Young and Old(Tenured)
Initially, objects are created in the young generation. It is further divided into:
- Eden space
- Survivor space (from space and to space)
Eden space is where objects are actually created. When Eden space gets full, GC kicks in and performs a minor garbage collection operation. The objects which are marked as reachable are then moved to different Survivor spaces and later during minor GC operation, reachable objects will be moving to and fro between survivors. Finally, after several generations it will be moved to the old generation.
Objects are usually moved from survivor space to the old generation only when the maximum tenuring threshold limit has reached. In the old generation, objects will slowly become unreachable and subjected to major GC operations to free up heap memory allocated for that application. But often that is not the only case where major CG performed. When the heap is full and wants memory to store an object then a major GC operation occurs.
GC in Java are subdivided into:
This is the basic GC that runs in a single thread. It is specially designed for smaller applications. All the GC events will happen serially with a single thread.
This GC is specially designed for large applications that run on multiprocessor or multithreaded environments. Multiple threads are used for minor garbage collection that occurs in young generation.
Parallel Old GC:
It is the same as Parallel GC except that it uses multiple threads for both young and old generations.
In a concurrent collector, multiple threads are used in minor garbage collection with the same algorithm used in parallel GC. It runs concurrently along with application threads to avoid “stop the world” situation. This GC uses more CPU than any other GCs.
Garbage First GC:
This is specially designed for multithreaded applications that have larger heap size. This GC is quite different from other GCs as there won’t be Young and Old generation. Instead there will be a set of equal size regions and uses multiple threads to scan them.
This was released along with JDK 11. It handles memory allocation but doesn’t provide a memory reclamation mechanism. Once the allocated heap is full, JVM will shutdown. This GC is very rarely used and fit only for ultra-latency-sensitive applications.
This was released along with JDK 11 and improvised in JDK 12. This is mainly intended for applications which require low latency and/or use a very large heap.
This was released along with JDK 12. It is more intensive than any other GCs as it cleans garbage, compact live objects, and free up RAM immediately back to OS.
GC is an automatic memory manager that performs certain operations to allocate and deallocate objects from heap memory. Objects that are reachable will be kept in the memory and objects that are unreachable will be removed to free up space for the application. GC will perform this action until the application lifetime so that it runs smoothly.
I hope this article helped you to understand something about Garbage Collector.