Skip to content

JVM GC Metrics to Monitor

"Is my JVM healthy?" is not a feeling — it is a handful of numbers. These are the GC metrics worth watching in production, what each one tells you, and the ranges that should not raise an eyebrow.

1. GC throughput

What it is: the percentage of total time the application (not the collector) runs.

throughput = (total time − total GC time) / total time × 100%

Healthy: ≥ 95% for latency-sensitive services; batch jobs can live with less. Below 90% a tenth of your CPU budget is spent collecting garbage — tune it.

2. Pause times (avg / P99 / max)

What it is: how long the JVM stops all application threads for a stop-the-world collection.

Healthy: depends on your SLO — under 50 ms average is comfortable for most services; a max pause above 1 s is worth investigating no matter what. Watch P99, not just the average: users feel the tail.

3. Collection counts (Young vs Full)

What it is: how many minor and major collections happened in the log window.

Healthy: frequent Young GCs are normal (objects die young). Full GC count should be 0 — every Full GC stops the whole JVM and is the most expensive collection. Recurring Full GCs mean the old generation is under pressure.

4. Allocation rate

What it is: the speed at which your application creates objects (MB/s), derived from how fast the young generation fills between collections.

Healthy: there is no absolute number — watch it for changes. A sudden jump after a release usually explains new GC pressure.

5. Promotion rate

What it is: how fast objects survive the young generation and move into the old generation (MB/s).

Healthy: low and stable. A rising promotion rate fills the old generation faster → more Full GCs. Only available from detailed (Java 8 style) logs.

6. Heap occupancy after GC

What it is: how much heap remains after every collection — the "floor" your live data set needs.

Healthy: a stable band. Step-by-step growth of the after-GC line is the classic memory-leak signal.

7. CPU time of collections

What it is: user / sys / real time consumed by GC threads (from the [Times: user=… sys=… real=…] log suffix).

Healthy: user ≈ real × cores for parallel collectors. High sys time can hint at page faults or NUMA effects.

Measure all of them in one shot

These seven metrics are exactly what the EasyGC report computes from a single GC log — no agent, no APM setup:

Analyze a GC log now →