Stackify is now BMC. Read theBlog

What is Java Garbage Collection? How It Works, Best Practices, Tutorials, and More

By: Alexandra
  |  February 28, 2024
What is Java Garbage Collection? How It Works, Best Practices, Tutorials, and More

At Stackify, we battle our fair share of code performance problems too, including issues surrounding Java garbage collection. In this post, we’ll take a look at Java garbage collection, how it works, and why it matters.

Java garbage collection is the process by which Java programs perform automatic memory management

A Definition of Java Garbage Collection

Java garbage collection is the process by which Java programs perform automatic memory management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM for short. When Java programs run on the JVM, objects are created on the heap, which is a portion of memory dedicated to the program. Eventually, some objects will no longer be needed. The garbage collector finds these unused objects and deletes them to free up memory.

How Java Garbage Collection Works

Java garbage collection is an automatic process. The programmer does not need to explicitly mark objects to be deleted. The garbage collection implementation lives in the JVM. Every JVM can implement garbage collection however it pleases. The only requirement is that it should meet the JVM specification. Although there are many JVMs, Oracle’s HotSpot is by far the most common. It offers a robust and mature set of garbage collection options.

What are the Various Steps During the Garbage Collection?

While HotSpot has multiple garbage collectors that are optimized for various use cases, all its garbage collectors follow the same basic process. In the first step, unreferenced objects are identified and marked as ready for garbage collection. In the second step, marked objects are deleted. Optionally, memory can be compacted after the garbage collector deletes objects, so remaining objects are in a contiguous block at the start of the heap. The compaction process makes it easier to allocate memory to new objects sequentially after the JVM allocates the memory blocks to existing objects.

How Generational Garbage Collection Strategy Works

All of HotSpot’s garbage collectors implement a generational garbage collection strategy that categorizes objects by age. The rationale behind generational garbage collection is that most objects are short-lived and will be ready for garbage collection soon after creation.

Java Garbage Collection Heaps

Image via Wikipedia

What are Different Classification of Objects by Garbage Collector?

We can divide the heap into three sections:

  • Young Generation: Newly created objects start in the Young Generation. The garbage collector further subdivides Young Generation into an Eden space, where all new objects start, and two Survivor spaces, where it moves objects from Eden after surviving one garbage collection cycle. When objects are garbage collected from the Young Generation, it is a minor garbage collection event.
  • Old Generation: Eventually, the garbage collector moves the long-lived objects from the Young Generation to the Old Generation. When objects are garbage collected from the Old Generation, it is a major garbage collection event.
  • Permanent Generation: The JVM stores the metadata, such as classes and methods, in the Permanent Generation. JVM garbage collects the classes from the Permanent Generation that are no longer in use.

During a full garbage collection event, unused objects from all generations are garbage collected.

What are Different Types of Garbage Collector?

HotSpot has four garbage collectors:

  • Serial: All garbage collection events are conducted serially in one thread. JVM executes the compaction after each garbage collection.
  • Parallel: JVM uses multiple threads for minor garbage collection. It uses a single thread for major garbage collection and Old Generation compaction. Alternatively, the Parallel Old variant uses multiple threads for major garbage collection and Old Generation compaction.
  • CMS (Concurrent Mark Sweep): Multiple threads are used for minor garbage collection using the same algorithm as Parallel. Major garbage collection is multi-threaded, like Parallel Old. Still CMS runs concurrently alongside application processes to minimize “stop the world” events (i.e., when the garbage collector running stops the application). Here, the JVM does not perform compaction of memory.
  • G1 (Garbage First): The newest garbage collector is intended as a replacement for CMS. It is parallel and concurrent, like CMS. However, it works quite differently under the hood than older garbage collectors.

Benefits of Java Garbage Collection

The biggest benefit of Java garbage collection is that it automatically handles the deletion of unused objects or objects that are out of reach to free up vital memory resources. Programmers working in languages without garbage collection (like C and C++) must implement manual memory management in their code.

Despite the extra work required, some programmers argue in favor of manual memory management over garbage collection, primarily for reasons of control and performance. While the debate over memory management approaches continues to rage on, garbage collection is now a standard component of many popular programming languages. For scenarios in which the garbage collector is negatively impacting performance, Java offers many options for tuning the garbage collector to improve its efficiency.

What Triggers Garbage Collection?

The Garbage Collection process is triggered by a variety of events that signal to the Garbage Collector that memory needs to be reclaimed.

Here are some common events that trigger Java Garbage Collection:

  1. Allocation Failure: When an object cannot be allocated in the heap because there is not enough contiguous free space available, the JVM triggers the Garbage Collection to free up memory.
  2. Heap Size: When the heap reaches a certain capacity threshold, the JVM triggers Garbage Collection to reclaim memory and prevent an OutOfMemoryError.
  3. System.gc(): Calling the System.gc()  method can trigger Garbage Collection, although it does not guarantee that Garbage Collection will occur.
  4. Time-Based: Some Garbage Collection algorithms, such as G1 Garbage Collection, use time-based triggers to initiate Garbage Collection.

Ways for requesting JVM to run Garbage Collector

There are several ways to request the JVM to run Garbage Collector in a Java application:

System.gc() method:

Calling this method is the most common way to request Garbage Collection in a Java application. However, it does not guarantee that Garbage Collection will occur as it is only a suggestion to the JVM.

Runtime.getRuntime().gc() method:

This method provides another way to request Garbage Collection in a Java application. This method is similar to the System.gc() method, and it also suggests that the JVM should run Garbage Collector, but again it does not guarantee that Garbage Collection will occur.

JConsole or VisualVM:

JConsole or VisualVM is a profiling tool that is included with the Java Development Kit. These tools provide a graphical user interface that allows developers to monitor the memory usage of their Java application in real-time. They also provide a way to request Garbage Collection on-demand by clicking a button.

Command-Line Options:

The JVM can be configured with various command-line options to control Garbage Collection. For example, the -Xmx option can be used to specify the maximum heap size, which can affect the frequency and duration of Garbage Collection events. The -XX:+DisableExplicitGC option can be used to disable explicit calls to System.gc() or Runtime.getRuntime().gc().

Heap Dumps:

Heap dumps are snapshots of the Java heap that can be taken at any time during the application’s execution. They can be analyzed to identify memory leaks or other memory-related issues. Heap dumps can be requested using command-line options or profiling tools.

It is worth noting that requesting Garbage Collection too frequently can negatively impact the performance of the application. It is important to monitor the memory usage of the application and only request Garbage Collection when it is necessary. By using profiling tools and selecting appropriate Garbage Collection algorithms, developers can ensure that Garbage Collection is triggered in a way that minimizes the impact on the application’s performance.

Why Does a Programmer need to Understand Garbage Collection?

For many simple applications, Java garbage collection is not something that a programmer needs to consciously consider. However, for programmers who want to advance their Java skills, it is important to understand how Java garbage collection works and the ways in which it can be tuned.

Besides the basic mechanisms of garbage collection, one of the most important points to understand about garbage collection in Java is that it is non-deterministic, and there is no way to predict when garbage collection will occur at run time. It is possible to include a hint in the code to run the garbage collector with the System.gc()  or Runtime.getRuntime().gc()  methods, but they provide no guarantee that the garbage collector will actually run.

The best approach to tuning Java garbage collection is setting flags on the JVM

Java Garbage Collection Best Practices

The best approach to tuning Java garbage collection is setting flags on the JVM. Various flags such as the initial and maximum size of the heap, the size of the heap sections (e.g. Young Generation, Old Generation), can adjust the garbage collector to be used (e.g. Serial, G1, etc.). The nature of the application being tuned is a good initial guide to settings. For example, the Parallel garbage collector is efficient but will frequently cause “stop the world” events, making it better suited for backend processing where long pauses for garbage collection are acceptable.

On the other hand, the CMS garbage collector is designed to minimize pauses, making it ideal for GUI applications where responsiveness is important. Additional fine-tuning can be accomplished by changing the size of the heap or its sections and measuring garbage collection efficiency using a tool like jstat.

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Additional Resources and Tutorials on Java Garbage Collection

Visit the following resources and tutorials for further reading on Java garbage collection:

Improve Your Code with Retrace APM

Stackify's APM tools are used by thousands of .NET, Java, PHP, Node.js, Python, & Ruby developers all over the world.
Explore Retrace's product features to learn more.

Learn More

Want to contribute to the Stackify blog?

If you would like to be a guest contributor to the Stackify blog please reach out to stackify@stackify.com