How memory management (Garbage Collection) works in Java and difference types of Garbage Collectors in Java

Introduction

Garbage Collector is heart of JVM and Java language. Because this is one the most important features provide by Java for memory management. Garbage collection has played a significant role in popularity of Java in software industries. Garbage collector automatically de-allocates (free) memory after reclaiming dead objects from heap and release these reclaimed memory back to JVM to allocate new objects. Dead objects are those objects which are not in use and further referenced in program. Other programming languages before Java like C and C++, there are no garbage collectors kind of things available to manage memory. Memory management is required to be done explicitly by developer. This is the programmer’s responsibility to initialize new object and de-allocate memory after use. The complexity of that task leads to many common errors that can cause unexpected or erroneous program behavior and crashes. As a result, a large proportion of developer time is often spent debugging and trying to correct such errors. That is why garbage collection is one of the major reasons of popularity of Java. Before going deep to understand different types of garbage collectors, you must aware about JVM heap memory isolation in generation. There are basically three types of isolated generations on heap, which are young generation, old generation and permanent generation. But there are few terms, which are required to be known before reading this blog. These terms are mentioned below:

  1. Live Objects: Live objects are those objects which are still referenced in program and could be use later on in program.
  1. Dead Objects: Dead objects are those objects which are no longer used and referenced in program or out of scope of program. These dead objects are termed as garbage.
  1. Fragmentation: This is the limitation of garbage collection. When the memory for garbage objects is freed, the free space may appear in small chunks in various areas such that there might not be enough space in any one contiguous area to be used for allocation of large object.
  1. Compaction: This is a approach to eliminating fragmentation from memory and known as compaction. Compaction moves all live objects to one side of memory and other side of memory is free to allocate new objects.
  1. Throughput: The percentage of total time not spent on garbage collection, considered over long periods of time. In other word, effectively time spent by application without garbage collection overhead.
  1. Garbage Collection Overhead: The inverse of throughput, that is, the percentage of total time spent in garbage collection.
  1. Pause Time: The length of time during which application execution is stopped while garbage collection is occurring.
  1. Stop-The-World: Stop-the-world is term used for time period, while application is totally halt for garbage collection.
  1. Frequency of Collection: How often garbage collection occurs, relative to application execution.
  1. Footprint: Measurement of heap size, which describes used and free space available in heap.
  1. Promptness: The time between when an object becomes garbage and when the memory becomes available.

 

Generations

Heap memory is divided into multiple parts which are termed as generations. Garbage collectors works differently on different generations. There are mainly three generations isolated into heap. These generations have different memory pools holding objects of different ages. Different garbage collector algorithms can be used to perform garbage collection. There are few important observation which are good to know that most allocated objects are not referred for much longer and they died at young stage Only few objects get survive from this stage and get alive. Few reference from older to younger objects also exists.

Three generations are mentioned bellow, which holds allocated objects of different ages:

java_memory

  1. Young Generation (Eden + 2 Survivors): Most of new objects are allocated in this generation (Eden). Young generation garbage collection occurred relatively more frequently than other generations and this is faster than other generation because young generation is comparatively small and most of objects are no longer referred. Only few survive objects are promoted to next survivor area. There are two survivor areas, which hold those objects which are not garbage and survived from garbage collection. Objects those survived some number of garbage collections are eventually promoted or tenured to the old generation.
  1. Old Generation (Tenured): All survived objects from young generation are promoted to old generation (Tenured) and some large objects which are directly allocated in old generation. Old generation is larger than young generation. Garbage collection is less frequent in this generation and also takes significantly longer to complete collection.
  1. Permanent Generation (PermGen): PermGen contains all relevant data or meta-data of JVM such as classes and methods objects. PermGen is divided into two areas, read-only and read-write areas, which contain different types of objects.

 

Fast Memory Allocation

As you know garbage collection and memory allocation to objects are equally important processes. Therefore, objects allocation must be as faster as we expect garbage collection. There are few techniques used to fast the allocation, one is Bump-The-Pointer technique. In this technique one pointer always track end of the previously allocated object and check whether new object is satisfying or fit for available memory, if yes, update the pointer and initialize the object. In other hand, for multithreaded application, objects allocation operation need to be multithread safe. If global locks were used to ensure this, allocation into a generation would degrade performance. Therefore, to solve this issue, another technique is used for multithreaded applications. This technique is calledThread-Local-Allocation-Buffers (TLABs). This improves multithreaded allocation throughput by giving each thread its own buffer (i.e., a small portion of the generation) from which to allocate. Since only one thread can be allocating into each TLAB, allocation can take place quickly by utilizing the Bump-The-Pointer technique, without requiring any locking. Only infrequently, when a thread fills up its TLAB and needs to get a new one, must synchronization be utilized. Several techniques to minimize space wastage due to the use of TLABs are employed. For example, TLABs are sized by the allocator to waste less than 1% of Eden, on average. The combination of the use of TLABs and linear allocations using the Bump-The-Pointer technique enables each allocation to be efficient, only requiring around 10 native instructions.

Design and Algorithms

Garbage collection use different types of designs and algorithms, which would be better to know before drill down garbage collector types.

Garbage-Collector

  1. Serial versus Parallel: In serial collector, only one thing happens at a time. Even when multiple CPUs are available, only one is utilized to perform to collection. When parallel collection is used, garbage collection is split into parts and those subparts are executed simultaneous on different CPUs.
  1. Concurrent versus Stop-The-World: When Stop-The-World garbage collection takes place, it suspends application execution and performs garbage collection. Whereas, concurrent garbage collection and application execution are work concurrently. Concurrent garbage collection does most of its works concurrently with application execution, that is why, its throughput is much higher that Stop-The-World. But occasionally its do few Stop-The-World pauses during concurrent garbage collection. Stop-The-World is simpler than concurrent garbage collection because Stop-The-World stop application execution and freeze heap and objects do not change during collection. In other hand, concurrent garbage collection need extra care during collection because might be objects which are going to collect are updated at time of collection by application.
  1. Compacting versus Non-compacting versus Copying: When garbage collector analysis which objects are live and garbage, then all live objects are moved towards start of memory, which is called compaction and rest of objects (garbage) reclaimed to release the memory. After compaction it is easy to allocate new objects in memory because Bump-The-Pointer technique track last memory available after compacted objects. Opposite to compacting collection, a non-compacting collection does not move live objects, instead of this it remove all garbage from memory and leave fragmented space in heap. That is why non-compacting collection is much faster than compacting collection but it is expensive to allocate new objects on heap. A third alternative is a copying collector, which copies or evacuates live objects to a different memory area. The benefit is that source area can then be considered empty and available for fast and easy subsequent allocations. But the drawback is additional time required for copying and the extra space that may be required.

 

Types of Garbage Collectors

There are five types of garbage collectors available in JVM.

GC-Compare

1. Serial Collector: With the serial collector, both young and old collections are done serially (using single CPU), in a stop-the-world fashion. That is application execution is halted while collection is taking place. Throughput of serial collector is very low with high pause time, because during collection every task is done with stop-the-world fashion. Click here to read more about serial collector.

2. Parallel Collector: You know these days many machines run on lots of memory and multiple CPUs. Therefore parallel collector take advantage of multiple CPUs with parallel execution of garbage collection with multiple threads. Therefor throughput of parallel collector is better than serial collector because most of work are done parallel rather that idle the CPU when one garbage collection is working. Click here to read more about parallel collector.

3. Parallel Compacting (Old) Collector: Parallel compacting collector was introduced since Java 5. Parallel compacting collector works similar way as parallel collector work, but it use one new algorithms to compact the live objects in one side to remove fragmentation from heap. Parallel compacting collector is collect garbage in Stop-The-World fashion and compaction of live objects are done parallel with this. This is much more complex that parallel collector. Throughput of parallel compacting is less than parallel collector but new object allocation is faster. Click here to read more about parallel compacting collector.

4. Concurrent Mark-Sweep (CMS) Collector: For many applications those required high throughput and less pause time, concurrent mark-sweep (CMS) is much beneficial for these types of applications. CMS collector is inspired by parallel collector but it also work concurrently with application throughput as well. Therefore, it introduce very short pause time (Stop-The-World) in application execution and provide good throughput. Click here to read more about Concurrent Mark Sweep garbage collector.

5. Garbage First (G1) Collector: The Garbage First Garbage Collector (G1 GC) is latest garbage collection implementation in Java HotSpot VM. This garbage collector (G1) in introduced since Java 6 for testing phase. But since Java 7, Garbage First (G1) is officially supported. G1 is low-pause, server style garbage collector, which is design to achieve more throughputs from application. G1 determine the areas where large amount of garbage (dead objects) exists, G1 collect those area first. That is why, this garbage collector is known as Garbage First (G1). Throughput of G1 is much higher with low pause time. G1 algorithm does not work on generations (young, old and permanent) as previous algorithms works. Instead of it G1 break down whole heap in small equal sizes memory reasons. These individual reason hold objects of different ages. Now these individual reason logically hold young, survivor and tenured objects.

Conclusion

Now you know garbage collection is not just a feature of JVM. It is one of most significant feature of Java and one of the biggest thing to play a big role in success of Java. With deep understanding of objects age  generations on heap and all available garbage collector types, you can give a new life and good performance to your software. With the help of this article now you can select your own garbage collector, which suites you best for your application. I hope you will take full advantage of this GC customization.

Deals on Tablets, Get up to 25% off on Tablets - Dell, Lenovo, Samsung, HCL and others.