How Generational Garbage Collection Works in Java

Jill ThornhillJill Thornhill
4 min read

What is generational garbage collection (GC)? In broad terms, the GC places objects in memory in different areas, categorized by age. Not all areas are collected on every GC cycle.

In this article, we’ll look into this concept in more detail, discuss the theory behind it, and see how it works in practice.

What is Java Garbage Collection?

In Java, developers don’t have to specifically release memory when they’ve finished with it. Instead, the GC keeps a record of all pointers referencing each object. When an object no longer has any references, it’s treated as garbage and swept from memory. The memory can then be reused for new objects.

What causes an object to have no references? It happens either when the block in which they were defined, or used, is completed, so that the objects go out of scope. It also happens if the programmer explicitly sets a reference to null, or closes an object such as a stream.

Generational GC: The Theory

The generational hypothesis in memory management postulates that the majority of objects are likely to ‘die young’. Some objects, in fact, have very short life spans, such as the iterator in a for … loop. Local variables created within a method only last for the duration of the method. A few objects, of course, are created in an outer block, and live much longer.

This is illustrated in Oracle’s infographic showing bytes allocated vs bytes surviving GC in a typical program.

It makes sense, then, to prioritize recently-created objects for GC.

Generations in Java Garbage Collection

The Java heap is a common area that stores objects created by all classes in a program. It’s divided into spaces as shown in the diagram below.

Fig: The Java Heap Spaces

The major divisions are the Young Generation (YG) and Old Generation (OG), which is often referred to as the tenured generation. YG is usually much smaller, and is subdivided into:

  • Eden Space: New objects are always created here;

  • S1 and S2: Objects that survive GC in Eden are moved to one of these spaces, which are used alternately.

The JVM maintains a record of the age of each object. A JVM parameter, the tenuring threshold, specifies how long an object should exist before being promoted to an older generation. As well as sweeping away garbage, the GC is responsible for moving tenured objects to the OG.

Major and Minor GC Events

When the Eden space is filled to a defined percentage, a minor GC event is initiated. This cleans the YG only, moving survivors from Eden into S1 or S2. Tenured objects are promoted into the OG. Minor events are very quick, since the YG is usually small, and they run frequently.

When the OG is filled to its threshold, a major GC event is invoked. This does a full clean of both the heap and the metaspace, and takes much longer. Major GC events should not run frequently if the GC is tuned correctly.

Algorithms That Don’t Use Generational GC

Generational GC was introduced as early as Java 1.2, and is used by almost all GC algorithms. However, the early versions of ZGC did not use this method. Later, in Java 17, ZGC introduced the option of using generational GC, which later became its default. Prior to Java 17, this algorithm may not perform well for this reason.

Shenandoah is currently non-generational, but is expected to release a generational option shortly.

We can choose not to use generational GC in these two algorithms if we have an application that doesn’t fit with the generational hypothesis. Gaming programs, for instance, may retain objects for much longer periods.

Java Garbage Collection: Monitoring and Tuning

Inefficient GC can have a huge impact on application performance. Since every application is different, we can only achieve best results by monitoring GC and tuning the JVM accordingly.

The JDK does include basic monitoring tools, such as jstat and jvisualvm. For comprehensive diagnostics and tuning suggestions, the GCeasy tool is well worth evaluating.

You can tune GC using various JVM parameters, such as tenuring threshold, fill threshold, the size of each of the heap spaces and the GC algorithm to be used.

I suggest further reading on Java garbage collection operations and tuning, where you’ll find useful links to tuning guides for each GC algorithm.

Conclusion

Understanding Java’s generational garbage collection helps you analyze monitoring statistics, and tweak your applications for better performance.

0
Subscribe to my newsletter

Read articles from Jill Thornhill directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jill Thornhill
Jill Thornhill