How Java Garbage Collection Works
Table of Contents
What is Garbage Collection #
Garbage collection is the process of automatically managing memory in Java. When you create an object in Java, the memory is allocated to the object on the heap. When the object is no longer needed, the memory occupied by the object is reclaimed by the garbage collector.
Not all languages have garbage collection. In languages like C and C++, you have to manually allocate and deallocate memory. This can lead to memory leaks and other memory-related issues if not done correctly.
Java has an automatic garbage collection mechanism that runs in the background and reclaims memory that is no longer needed. This makes Java memory management easier and less error-prone.
Stop-the-World Pauses #
One of the main drawbacks of garbage collection is stop-the-world pauses. When the garbage collector runs, it stops all application threads to perform garbage collection. This can lead to latency issues in real-time applications, where even a small pause can cause problems.
To minimize the impact of stop-the-world pauses, Java has different garbage collection algorithms and strategies that can be tuned based on the application’s requirements.
How is Memory Managed in Java #
Java memory is divided into two main areas: the stack and the heap.
-
Stack: The stack is used for static memory allocation and contains primitive data types and references to objects in the heap. Each thread in Java has its own stack, which is used to store method calls and local variables.
-
Heap: The heap is used for dynamic memory allocation and contains objects and arrays. When you create an object in Java using the
newkeyword, the memory for the object is allocated on the heap.
Note that prior to Java 8, the Permanent Generation was used to store class metadata. In Java 8 and later, the Permanent Generation has been replaced by the Metaspace.
Generational Garbage Collection #
Java uses a generational garbage collection algorithm to manage memory. The heap is divided into different generations based on the age of the objects.
-
Young Generation: The Young Generation is where new objects are allocated. It is divided into three parts: Eden Space, Survivor Space 1, and Survivor Space 2. When an object is created, it is allocated in the Eden Space. When the Eden Space is full, a minor garbage collection is triggered, and the surviving objects are moved to one of the Survivor Spaces. Objects that survive multiple garbage collections are eventually moved to the Tenured space.
-
Tenured The Tenured Space, also known as Old Generation, is where long-lived objects are stored. When an object survives multiple garbage collections in the Young Generation, it is promoted to the Tenured space. The Tenured space is collected less frequently than the Young Generation.
Why Generational Garbage Collection #
The generational garbage collection algorithm is based on the observation that most objects die young. By dividing the heap into different generations, the garbage collector can optimize its collection strategy based on the age of the objects. This allows the garbage collector to focus on the Young Generation, where most of the garbage is collected, and minimize the impact on the Tenured space.
Mark-and-Sweep Algorithm #
The mark-and-sweep algorithm is a common algorithm used in garbage collection. It works by marking live objects and sweeping away dead objects. The algorithm has two phases:
-
Mark Phase: In the mark phase, the garbage collector traverses the object graph starting from the root objects (objects that are directly accessible from the stack) and marks all live objects. This is done by setting a flag on the object to indicate that it is live.
-
Sweep Phase: In the sweep phase, the garbage collector scans the heap and deallocates objects that are not marked as live. This frees up memory that can be used to allocate new objects.
Minor, major, and Full Garbage Collection #
Garbage collection in Java can be divided into three main types: minor, major, and full garbage collection.
Minor Garbage Collection #
Minor garbage collection works on the Eden space. It is triggered when the Eden space is full. During minor garbage collection, live objects are identified and moved to the Survivor spaces.
Major Garbage Collection #
Major garbage collection works on the Tenured space. It is triggered when the Tenured space is full. During major garbage collection, live objects are identified and compacted to reduce fragmentation. Major GC focuses on this area because objects in the Old Generation are assumed to have longer lifetimes compared to those in the Young Generation.
Full Garbage Collection #
Full garbage collection works on the entire heap, including the Young Generation and the Tenured space. It is triggered when there is not enough memory to allocate new objects. Full garbage collection is more expensive than minor and major garbage collection because it has to scan the entire heap. It is also a stop-the-world event, where all application threads are paused to allow the GC to execute.
Types of Garbage Collectors in Java #
There are several garbage collectors available in Java, each with its own characteristics and performance trade-offs. Here are some of the commonly used garbage collectors and their features and performance.
Serial Garbage Collector #
- Description: The Serial garbage collector is a single-threaded collector that stops all application threads during garbage collection. It is suitable for small applications or environments with limited resources.
- Performance: The Serial garbage collector has low memory footprint and low pause times, but it can cause significant application pauses during garbage collection.
Parallel Garbage Collector #
- Description: The Parallel garbage collector uses multiple threads to perform garbage collection. It is designed to take advantage of multi-core processors and is suitable for applications with large heaps.
- Performance: The Parallel garbage collector can achieve high throughput and reduced pause times compared to the Serial collector. However, it may consume more CPU resources and may not be suitable for latency-sensitive applications.
CMS Garbage Collector #
- Description: The CMS (Concurrent Mark Sweep) garbage collector performs garbage collection concurrently with the application threads. It is designed to minimize pause times and is suitable for applications that require low latency.
- Performance: The CMS garbage collector can achieve low pause times and is suitable for applications that prioritize responsiveness. However, it may introduce additional CPU overhead and may not be as efficient as other collectors for throughput-oriented workloads.
G1 Garbage Collector #
- Description: The G1 (Garbage-First) garbage collector is a generational collector that divides the heap into regions and performs garbage collection incrementally. It is designed to provide consistent pause times and high throughput.
- Performance: The G1 garbage collector can achieve low pause times and high throughput for most applications. It is suitable for large heaps and can dynamically adapt its behavior based on the application’s requirements.
Z Garbage Collector #
- Description: The Z garbage collector is a low-pause collector that is designed to minimize pause times and provide consistent performance. It is available as an experimental feature in Java 11 and later versions.
- Performance: The Z garbage collector aims to provide low and predictable pause times, making it suitable for latency-sensitive applications. However, it may not be as mature or widely tested as other garbage collectors.
It is important to note that the performance characteristics of garbage collectors can vary depending on the specific workload and configuration. It is recommended to benchmark and tune the garbage collector based on the application’s requirements and performance goals.
Setting Garbage Collection Options #
You can configure the garbage collector in Java by setting various options using the -XX command-line flags. Here are some common options that you can use to tune the garbage collector:
-XX:+UseSerialGC: Use the Serial garbage collector.-XX:+UseParallelGC: Use the Parallel garbage collector.-XX:+UseConcMarkSweepGC: Use the CMS garbage collector.-XX:+UseG1GC: Use the G1 garbage collector.-XX:+UseZGC: Use the Z garbage collector (experimental feature).-Xms: Set the initial heap size.-Xmx: Set the maximum heap size.