Yet Another Post About Java Heap Space
Generational Garbage Collectors
JVM heap is divided into two different Generations. One is called Young and the second one is the Old (sometimes referred to as Tenured). The Young Generation is further separated into two main logical sections: Eden and Survivor spaces. There are also Virtual spaces for both Young and the Old Generations which are used by Garbage Collectors to resize other regions – mainly to meet different GC goals.
Weak Generational Hypothesis
Why is heap divided into the Young and Old Generations? It’s because lots of objects are usually created and used for a relatively short period of time. This observation is called Weak Generational Hypothesis in GC theory. Imagine some objects created and used only inside the loop – assuming that they are not going to be scalarized, every iteration discards previously created objects and creates new ones.
Objects start their journey in Eden of the Young Generation. When Eden fills up, so called Minor GC is performed: all application threads are stopped (stop-the-world pause), objects which are not used anymore are discarded and all other objects from the Eden are moved to the first Survivor space (S0). Next time a Minor GC is performed, the objects goes from S0 to the second Survivor space (S1). All live objects from Eden goes to S1 as well. Notice that it leads to differently aged object in the Survivor space – we have objects from Eden and objects which were already in the Survivor space. Next iteration of Minor GC moves the objects from S1 back to the S0, so the Survivor spaces switch every GC. Why do we have two Survivor spaces and why do we switch them? It’s pretty simple – when the object reaches certain age threshold, it is promoted to the Old Generation. It leads to Survivor space fragmentation which can be easily eliminated with moving all objects from S0 to S1 and back every Minor GC.
Eventually, when the Old Generation fills up, a Major GC will be performed on the Old Generation which cleans it up and compacts that space. If and how stop-the-world pauses occur during Major GC depends on specific GC algorithm used.
Besides Minor and Major GC, there is also a Full GC which is about cleaning the entire heap – both Young (by Minor GC) and Old (Tenured) (by Major GC) Generations. Because normally Full GC is triggered by Minor GC – Eden gets full and additionally Young to Old promotion fails due to full Tenured space, we usually talk about Full GC instead of Major GC. There is a great Nikita Salnikov-Tarnovski’s article about differences between these terms.
There are two main advantages of having the heap divided into two regions. Firstly, it’s always faster to process only some portion of the heap (stop-the-world pauses take less). Secondly, during Minor GC, all objects from Eden are either moved or discarded which automatically means that this part of the heap is compacted.