Logo

Understanding Garbage Collection in JVM

5 min read
JVMDatadog

Table of Contents

Introduction

My Java application was experiencing performance issues, and I suspected it was related to how the JVM was managing memory. To optimize performance, I needed a clear understanding of how garbage collection (GC) works in the JVM.

TL;DR – Watch out for Major GC!

What Is Garbage Collection (GC)?

Garbage Collection is the JVM’s automatic memory management process. It finds and removes objects that are no longer in use, preventing memory leaks and freeing up memory for new allocations.

How Java Applications Use Memory

Java splits memory into multiple areas:

1. Heap Memory

Example: new User() allocates memory in the heap.

2. Stack Memory

Example: int count = 5 goes on the stack.

3. Metaspace (Java 8+)

Example: Defining a class like class Product.

4. Code Cache

5. Native Memory

What Is the Heap?

Heap Structure

GenerationDescription
Young GenerationNew objects go here (Eden + Survivor).
Old GenerationLong-lived objects promoted here.
Metaspace(Not technically heap) Class metadata lives here.

GC Lifecycle Example

  1. User user = new User(); → Eden
  2. Survives GC → Survivor → Old Gen
  3. Becomes unreachable → Collected by GC

Heap Management Tips

Minor GC vs Major GC

TypeOperates OnFrequencyPerformancePause TimePurpose
Minor GCYoung GenerationFrequent (seconds)LowShortClean short-lived objects
Major GCOld GenerationRare (minutes+)HighLongClean long-lived objects
Full GCEntire Heap + MetaspaceEmergencyVery HighLongestFull memory cleanup

GC Spikes: What Do They Mean?

Minor GC Spikes

✅ Fixes:

Major GC Spikes

✅ Fixes:

How Heap Size Is Determined

Heap does not grow with system memory by default. Use:

Memory LimitDefault Max Heap
2 GB~512 MB – 1 GB
8 GB~2–4 GB
16 GB~4–8 GB

GC Metric Analysis

Minor Collection Count

1exclude_null(avg:jvm.gc.minor_collection_count{...})

Minor Collection Time

1exclude_null(avg:jvm.gc.minor_collection_time{...})

Major Collection Count

1exclude_null(avg:jvm.gc.major_collection_count{...})

Major Collection Time

1exclude_null(avg:jvm.gc.major_collection_time{...})

Old Gen Size

1exclude_null(avg:jvm.gc.old_gen_size{...})

What I Observed

  1. Minor GC spiked right after release.
  2. Major GC occurred days later (still microseconds).
  3. Old Gen size steadily increased.
  4. Memory usage jumped 40%.

Root Cause

Since it was caused by the release of a new service, We asked the devs to dig into the app to identify memory-heavy objects. A memory leak or retained reference was likely responsible.

Final TL;DR

Related Articles