In this post, I'm going to elaborate the concepts of Garbage Collection in java along with "How GC works in java".
Garbage Collection starts using GC roots and marks all live objects. Everything else is considered garbage.
OS allocates heap to be managed by JVM. As long as an object is referenced, JVM considers it as alive. Once an object is no longer referenced, the GC removes it and reclaims the unused memory.
So, Question becomes: What is the first reference in the tree?
Answer: Garbage-Collection-Roots--- The source of all Object Trees
Every object tree must have one or more root objects. As long as the application can reach those roots, the whole tree is reachable.
But when are those root objects considered reachable? Special objects called garbage-collection roots (GC roots; see Figure 1) are always reachable and so is any object that has a garbage-collection root at its own root.
There are four kinds of GC roots in Java:
· Local variables are kept alive by the stack of a thread. This is not a real object virtual reference and thus is not visible. For all intents and purposes, local variables are GC roots.
· Active Java threads are always considered live objects and are therefore GC roots. This is especially important for thread local variables.
· Static variables are referenced by their classes. This fact makes them de facto GC roots. Classes themselves can be garbage-collected, which would remove all referenced static variables.
· JNI References are Java objects that the native code has created as part of a JNI call. Objects thus created are treated specially because the JVM does not know if it is being referenced by the native code or not. Such objects represent a very special form of GC root.
Figure 1: GC roots are objects that are themselves referenced by the JVM and thus keep every other object from being garbage-collected.
Therefore, a simple Java application has the following GC roots:
· Local variables in the main method
· The main thread
· Static variables of the main class
Marking and Sweeping Away Garbage
To determine which objects are no longer in use, the JVM intermittently runs what is very aptly called a mark-and-sweep algorithm. As you might intuit, it's a straightforward, two-step process:
1. The algorithm traverses all object references, starting with the GC roots, and marks every object found as alive.
2. All of the heap memory that is not occupied by marked objects is reclaimed. It is simply marked as free, essentially swept free of unused objects.
Garbage collection is intended to remove the cause for classic memory leaks: unreachable-but-not-deleted objects in memory. However, this works only for memory leaks in the original sense. It's possible to have unused objects that are still reachable by an application because the developer simply forgot to dereference them. Such objects cannot be garbage-collected.
Question1:
As classes can be garbage collected, then what is the GC root for them?
Answer: Classloaders are GC roots for classes.
If there is nothing which can reach a classloader - which means nothing can reach any instances of classes created by that classloader , then both the classloader and the classes are eligible for garbage collection.
If there is nothing which can reach a classloader - which means nothing can reach any instances of classes created by that classloader , then both the classloader and the classes are eligible for garbage collection.
· Java 7 - Parallel GC
· Java 8 - Parallel GC
· Java 9 - G1 GC
· Java 10 - G1 GC
The older garbage collectors (serial, parallel, CMS) all structure the heap into three sections: young generation, old generation, and permanent generation of a fixed memory size.
All memory objects end up in one of these three sections.
The G1 collector takes a different approach.
The heap is partitioned into a set of equal-sized heap regions, each a contiguous range of virtual memory. Certain region sets are assigned the same roles (Eden, survivor, old) as in the older collectors, but there is not a fixed size for them. This provides greater flexibility in memory usage.
When performing garbage collections, G1 operates in a manner similar to the CMS collector.
G1 performs a concurrent global marking phase to determine the liveness of objects throughout the heap. After the mark phase completes, G1 knows which regions are mostly empty. It collects in these regions first, which usually yields a large amount of free space. This is why this method of garbage collection is called Garbage-First.
G1 copies objects from one or more regions of the heap to a single region on the heap, and in the process both compacts and frees up memory. This evacuation is performed in parallel on multi-processors, to decrease pause times and increase throughput.
Note: G1 has both concurrent (runs along with application threads, e.g., refinement, marking, cleanup) and parallel (multi-threaded, e.g., stop the world) phases.
· Used for apps that require large heaps with limited GC latency[pause time]. This means heap sizes of around 6GB or larger, and stable and predictable pause time below 0.5 seconds.
· The rate of object allocation varies significantly.
· Full GC durations are too long or too frequent.
· Undesired long garbage collection or compaction pauses.
When performing garbage collections, G1 operates in a manner similar to the CMS collector. G1 performs a concurrent global marking phase to determine the liveness of objects throughout the heap. After the mark phase completes, G1 knows which regions are mostly empty. It collects in these regions first, which usually yields a large amount of free space. This is why this method of garbage collection is called Garbage-First.
Nice article on GC. Well explained.
ReplyDelete