All 7 Java Garbage Collectors Explained

 

Transcript:

Today we are talking about garbage collection in Java. Hotspot JVM offers seven garbage collectors for various performance requirements. Let's look at all of them.

But first, a couple of words about how Java memory model works. Garbage collection in Java is automatic. An object is considered eligible for GC when it becomes unreachable, meaning that there are no references to it. Such objects are deleted by the garbage collector. One of the functions of a Java garbage collection is managing objects in generations. Mul created objects belong to the young generation. As a rule, most objects die young, but if they don't, they are promoted to the old generation or tenure generation. These generations occupy different spaces on the JVM hip. Eden space and two survivor spaces zero and one are where young objects live. Tenure space preserves the old generation. Metaspace stores metadata. It replaced perm used in Java versions earlier than JDK8. When any of these spaces fill up, garbage collection occurs. A minor collection happens when the young space stops up. If some objects are still used at the moment of garbage collection, they are promoted to uh survivor space zero and then to survivor space one. If they're still alive in survivor space one, they are promoted to uh old generation. As a result, they are moved to the tenure space. At some point, tenure space also gets filled up and that's when the major collection occurs. Major collections usually take more time because more objects are involved.

And now let's look at various Java garbage collectors in more detail. Serial GC is the simplest and the oldest collector in Java. It works in one thread and freezes all application threads while performing the collection. It is good for single threaded client side applications that uh don't uh require extra small post times. But there is a catch. If you limit your application to 2 GB of RAM and less than two processors, then the serial GC is enabled by default even if you explicitly enable another collector. So be careful about that.

Parallel GC is also called the throughput collector. It also freezes all application threads but works in multiple threads to perform the collection. By default, it works in multiple threads when uh performing the collection of the young generation and the old generation. You can set the number of worker threads, post times, and the time the application spends on a collection.

Concurrent mark sweep GC was used in earlier Java versions. It was designed for shorter poses and used multiple threads to perform the collection, but it is suitable for applications that can afford to share processor resources with the garbage collector. This collector was duplicated in Java 9 and removed in Java 14. G1GC was designed to replace CMSGC. It is now default garbage collector in Java. G1GC tries to provide a good balance between latency and throughput. It is a good fit for applications uh running in multiprocessor environments with heaps of 10 GB and more. G1 means garbage first. Just like other collectors, it works with young and old generations.

However, it splits the heap into multiple equals sized regions. First, it performs the global marking phase to determine which objects are alive. It does it concurrently with the application. Then it reclaims the space in the regions that are mostly filled with garbage. This way, it can free more space. This is why it's called garbage first. It performs the collection using evacuation. It copies and compacts objects from one or several regions into one or several regions. This way it avoids memory fragmentation. You can also tune this collector. You can set pause times, pause intervals and so on. ZC was first introduced in Java 11. It is a scalable low latency collector which is perfect for latency sensitive applications and applications with a very large heap of terabytes. ZC performs the expensive work concurrently and doesn't stop the application threads for more than 10 milliseconds. It requires minimal configuration.

In most cases, you just uh enable this collector and set uh the heap size and you're good to go. In Java 23, it became generational by default. It means that it maintains uh separate generations for young and old objects and collects young objects more frequently. It improves heap memory overhead and the garbage collection CPU overhead. Shannonova GC is also a low latency collector. It was first introduced in Java 12. It performs most of its work concurrently with the application including concurrent compaction. Therefore, the pulse times are not directly proportional to the hip size. Like Zachy, it is suitable for latency sensitive applications and applications with large heaps of terabytes. It became generational by default in JDK25. Oracle Java doesn't ship Shannono GC but it is available uh with various open GDK distributions including libera GDK.

Epsilon GC is a very interesting collector. It doesn't perform garbage collection and only allocates memory. Why would you need a garbage collector that doesn't collect any garbage you may ask? Well actually it has a purpose. First, you can use it for performance testing to see how fast the application will run without any garbage collection and see whether there are any performance bottlenecks that are not related to garbage collection. Also, you can use it with applications that almost don't allocate any garbage or you can use it with shortlived applications that don't have time to produce any garbage. This way, they may run faster without the garbage collection cycles. Another interesting feature of epsilon GC is that it will remain experimental forever. This is done to avoid enabling it accidentally in the production. So to use epsilon GC you need to explicitly unlock experimental VM options. And that was it about available garbage collectors in hotspot JVM.

Summary

This video explains how Java garbage collection works and compares all seven garbage collectors available in the HotSpot JVM. It describes the Java memory model, including young and old generations, as well as how minor and major collections occur. The video then reviews each collector: Serial GC for simple single-threaded apps, Parallel GC for higher throughput, the deprecated CMS, and G1GC—the current default designed for balanced performance. It also covers low-latency collectors like ZGC and Shenandoah, which perform most work concurrently and support huge heaps, and Epsilon GC, which performs no garbage collection and is useful for performance testing or short-lived applications. The guide highlights when each collector is appropriate and how they differ in latency, throughput, and scalability.

About Catherine

Java developer passionate about Spring Boot. Writer. Developer Advocate at BellSoft

Social Media

Videos
card image
Apr 2, 2026
Java Memory Options You Need in Production

JVM memory tuning can be tricky. Teams increase -Xmx and assume the problem is solved. Then the app still hits OOM. Because maximum heap size is not the only thing that affects memory footprint. The JVM uses RAM for much more than heap: metaspace, thread stacks, JIT/code cache, direct buffers, and native allocations. That’s why your process can run out of memory while heap still looks “fine”. In this video, we break down how JVM memory actually works and how to control it with a minimal, production-safe set of flags. We cover heap sizing (-Xms, -Xmx), dynamic resizing, direct memory (-XX:MaxDirectMemorySize), and total RAM limits (-XX:MaxRAMPercentage) — especially in containerized environments like Docker and Kubernetes. We also explain GC choices such as G1, ZGC, and Shenandoah, when defaults are enough, and why GC logging (-Xlog:gc*) is mandatory before tuning. Finally, we show how to diagnose failures with heap dumps and OOM hooks. This is not about adding more flags. It’s about understanding what actually consumes memory — and making decisions you can justify in production.

Videos
card image
Mar 26, 2026
Java Developer Roadmap 2026: From Basics to Production

Most Java roadmaps teach tools. This one teaches order — the only thing that actually gets you to production. You don’t need to learn everything. You need to learn the right things, in the right sequence. In this video, we break down a practical Java developer roadmap for 2026 — from syntax and OOP to Spring, databases, testing, and deployment. Structured into 8 levels, it shows how real engineers grow from fundamentals to production-ready systems. We cover what to learn and what to ignore: core Java, collections, streams, build tools, Git, SQL and JDBC before Hibernate, the Spring ecosystem, testing with JUnit, and deployment with Docker and CI/CD. You’ll also understand why most developers get stuck — jumping into frameworks too early, skipping SQL, or treating tools as knowledge. This roadmap gives you a clear path into real-world Java development — with priorities, trade-offs, and production context.

Further watching

Videos
card image
Apr 30, 2026
Java Flight Recorder Tutorial: How to Profile Java Applications

High CPU, GC spikes, or slow startup are common production issues, but logs and metrics don’t always reveal what the JVM is actually doing. Java Flight Recorder (JFR) provides a precise, low-overhead view of JVM behavior, safe for use even in production environments. In this video, you’ll learn how to use JFR to identify real bottlenecks such as CPU hotspots, memory allocation pressure, thread contention, and I/O stalls. We walk through the full workflow, including starting recordings with JVM flags, controlling them via jcmd, running JFR inside Docker containers, and attaching to live systems using ephemeral containers. Then we analyze a real Spring Boot recording in JDK Mission Control, breaking down GC behavior, allocation patterns, thread states, and method-level hotspots. If you want to move from symptoms to root cause with more confidence, this approach will help. Full article with commands and examples: [https://bell-sw.com/blog/how-to-profile-java-applications-with-jfr-beginner-s-guide/](https://bell-sw.com/blog/how-to-profile-java-applications-with-jfr-beginner-s-guide/)

Videos
card image
Apr 22, 2026
Dynamic SQL Queries with Spring Data JPA in 6 Minutes

If your repository layer has multiple queries for different filter combinations, your data access logic is already getting harder to maintain. In this video, we implement dynamic SQL queries in Spring Data JPA using Specifications — a composable approach that helps avoid query duplication and keeps your filtering logic clean. We build a flexible filtering system with optional parameters (category, language, format, price) and show how Specification.unrestricted() skips empty filters, while Specification.allOf(...) combines them into a single query. We also address a common issue: string-based field access. It’s fragile and can break at runtime when your model changes. Using the JPA Static Metamodel, we move to compile-time safety. The result is a cleaner, more maintainable way to implement dynamic filtering in Spring-based applications.

Videos
card image
Apr 8, 2026
Best Oracle Java Alternatives in 2026 Comparison of OpenJDK Distributions

A comparison of major OpenJDK distributions (Temurin, Liberica, Zulu, Corretto, Semeru, etc.), covering who maintains them, how updates are delivered, and what lifecycle guarantees they provide. We also explain why upstream OpenJDK isn’t production-ready and how your vendor choice impacts real-world systems. Useful for Spring Boot, containers, and Kubernetes to avoid hidden risks and choose the right runtime.