An Overview of Java Garbage Collectors

Transcript

Hi friends! Today, we are talking about Garbage Collectors in Java.

Choosing a right GC implementation may help you boost the app performance. HotSpot JVM offers seven collectors for various performance requirements. So, let’s look at all of them!

A couple of words about Java Memory Model

Young generation, old generation

Serial GC 

Serial GC is the simplest and the oldest collector in Java. It works in one thread and freezes all app threads while performing collection. It is good for single-threaded client-side applications that don’t need extra small pauses. But there’s a catch: if you limit your application to 2 GB RAM and less than 2 processors, SerialGC will be used automatically, even if you explicitly specify another collector! So be careful with that.


Parallel GC

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

Concurrent Mark Sweep GC

Concurrent Mark Sweep GC is designed for shorter pauses and uses multiple threads to perform the collection. But it is suitable for applications that can afford to share processor resources with the collector while the application is running. This collector was deprecated in Java 9 and removed in Java 14. 

G1 GC

G1 GC was designed to replace CMS GC. It is now a default garbage collector in Java. G1 GC tries to provide good balance between latency and throughput and is a very good fit for applications running in multiprocessor environments with a large heap of 10 gigabytes and more.

G1 means Garbage First. Just like other collectors, it works with young and old generations, but it splits the heap into multiple equal-sized regions. First, it performs global marking concurrently with the application and determines which objects are reachable. Then, it reclaims space in regions that are mostly filled with garbage, and so frees more memory, this is why it is called garbage first. G1 GC reclaims space using evacuation: it copies and compacts live objects from one or several regions into new regions.

Z GC

Z GC was first introduced in Java 11. It is a scalable low-latency collector, and it is great for latency-sensitive applications and applications with a very large heap of terabytes.

Z GC performs the expensive work concurrently and doesn’t stop the application threads for more than 10 ms. It requires minimal configuration, in most cases, just set the right heap size and you are good to go.

In Java 21, it became generational by default. It means that it maintains separate generations for young and old objects and collects young objects more frequently, which improves heap memory overhead and garbage collection CPU overhead.

Shenandoah GC

Shenandoah GC is also a low-latency collector introduced in Java 12. It performs most of its work concurrently with the app, including the concurrent compaction, so the pause times are not directly proportional to the heap size. Like Z GC, it is suitable for latency-sensitive applications and applications with a very large heap of terabytes. Oracle Java doesn’t ship Shenandoah, but this GC comes with major OpenJDK distributions including Liberica JDK.

Epsilon GC

Epsilon GC is a very interesting garbage collector. It doesn’t perform any garbage collection and only allocates memory. Why would you use a garbage collector that doesn’t collect any garbage? Well, it has a purpose. First, you can use it for performance testing to see how fast the program would run without any garbage collection and if there are performance bottlenecks not induced by the collector.

Also, you can use it with applications that almost don’t produce garbage. Or if the app is short-lived and doesn’t have time to leave garbage. Then the program may run faster without garbage collection cycles.

Another interesting feature of Epsilon GC is that it will remain an experimental feature forever so that you don’t accidentally use it in production. So, to use Epsilon GC, you need to explicitly enable experimental features.

Summary

Java provides multiple garbage collectors (GCs) tailored to different performance needs. Serial GC is ideal for single-threaded apps but pauses all threads, while Parallel GC uses multiple threads to prioritize throughput. G1 GC, the default collector, balances latency and throughput, making it suitable for large heaps, while Z GC and Shenandoah GC cater to low-latency and massive-heap applications by performing most tasks concurrently. Lastly, Epsilon GC skips garbage collection entirely, useful for testing or short-lived apps, but requires explicit enabling as an experimental feature.

About Catherine

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

Social Media

Videos
card image
Mar 9, 2026
jOOQ Deep Dive: CTE, MULTISET, and SQL Pipelines

Some backend developers reach the point where the ORM stops being helpful. Complex joins, nested result graphs, or CTE pipelines quickly push frameworks like Hibernate to their limits. And when that happens, teams often end up writing fragile raw SQL strings or fighting performance issues like the classic N+1 query problem. In this video, we build a healthcare scheduling application NeonCare using jOOQ, Spring Boot 4, and PostgreSQL, and show how to write production-grade SQL directly in Java while keeping full compile-time type safety.

Videos
card image
Feb 27, 2026
Spring Developer Roadmap 2026: What You Need to Know

Spring Boot is powerful. But knowing the framework isn’t the same as understanding backend engineering. In this video, I walk through the roadmap I believe matters for a Spring developer in 2026. We start with data. That means real SQL — CTEs, window functions, normalization trade-offs — and understanding what ACID and BASE actually imply for system guarantees. Spring Data JPA is useful, but you still need to know what happens underneath. Then architecture: microservices vs modular monolith, serverless, CQRS, and when HTTP, gRPC, Kafka, or WebSockets make sense. Not as buzzwords — but as design choices with trade-offs. Security and infrastructure follow: OWASP Top 10, AuthN vs AuthZ, encryption in transit and at rest, Docker, Kubernetes, Infrastructure as Code, and observability with Micrometer, OpenTelemetry, and Grafana. This roadmap isn’t about mastering every tool. It’s about knowing what affects reliability in production.

Further watching

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.

Videos
card image
Mar 19, 2026
TOP-5 Lightweight Linux Distributions for Containers

In this video, we compare five lightweight Linux distributions commonly used as base images: Alpine, Alpaquita, Chiseled Ubuntu, RHEL UBI Micro, and Wolfi. There are no rankings or recommendations — just a structured look at how these distros differ so you can evaluate them in your own context.