GC Pause Analysis

GC pause analysis uses garbage-collection logs and runtime metrics to determine why application threads were stopped and whether allocation pressure, evacuation, marking, compaction, or another GC phase is responsible. The goal is to connect pause duration and frequency to heap behavior and application symptoms rather than tuning JVM flags blindly.

A GC pause is a period during which some or all application threads are stopped while the JVM performs garbage-collection work. The exact work depends on the collector and phase, so a pause should be interpreted together with the GC event, heap occupancy, and collector-specific details.

Start by examining pause duration, frequency, and timing. A few long pauses can create latency spikes, while many short pauses can also matter if they occur frequently enough. Compare GC pauses with application latency, request throughput, CPU utilization, allocation rate, and heap occupancy to determine whether the collector is contributing to observed service degradation.

GC logs can reveal whether pauses correlate with young-generation collection, evacuation, concurrent-cycle phases, remarking, cleanup, or full-heap work. For example, high allocation pressure can cause frequent young collections, while insufficient space for object evacuation can lead to more expensive recovery behavior. The interpretation depends on the selected collector and its configuration.

A useful investigation separates cause from symptom. High heap usage does not automatically mean the heap is too small, and increasing the heap does not necessarily reduce every pause. Look for relationships among allocation rate, live-set size, promotion behavior, pause targets, CPU availability, and the amount of work performed during each event.

For production diagnosis, correlate GC events with application-level telemetry. Useful signals include p95/p99 latency, request rate, CPU, heap occupancy, allocation rate, and pause-time distributions. After a tuning change, compare equivalent workload periods rather than relying on a single unusually good or bad GC event.

Key points

Interview questions

What would you look at first when a Java service has intermittent high latency that appears to coincide with GC?

I would first inspect GC logs and determine whether a GC event occurred at the same time as the latency spike. Then I would check pause duration, frequency, heap occupancy before and after collection, and the type or phase of the collection. I would correlate those timestamps with application latency and CPU metrics. I would avoid changing JVM settings until the evidence identifies a likely cause.

What does a high allocation rate tell you during GC analysis?

A high allocation rate means the application is creating objects rapidly, which can increase the frequency of collections and the amount of GC work. It can explain frequent young-generation collections even when the long-lived heap is relatively stable. Allocation rate should be considered alongside pause duration, collector behavior, and application throughput. Reducing unnecessary allocation can sometimes address the underlying pressure more directly than simply increasing heap size.

How can GC logs help distinguish evacuation problems from allocation pressure?

Allocation pressure is suggested by rapid creation of garbage and correspondingly frequent collection activity. Evacuation problems are more specifically associated with difficulty moving live objects into available destination regions or spaces during a collection. The exact evidence depends on the collector, so I would inspect collector-specific log messages, region or generation occupancy, and the amount of live data involved. I would also check whether the JVM reports evacuation failure or related fallback behavior rather than inferring it from pause duration alone.

Why isn't increasing the Java heap always a solution for long GC pauses?

A larger heap can reduce collection frequency by providing more allocation headroom, but it can also increase the amount of memory that a collector may need to process. More importantly, it does not directly address excessive allocation, a large live set, CPU contention, or collector-specific pause work. The correct response depends on whether the dominant problem is allocation pressure, retained objects, evacuation, marking, compaction, or another phase. I would first establish the workload and collector behavior from logs and metrics, then test a targeted change.

How would you investigate a service whose p99 latency rises whenever GC pauses increase?

I would first establish temporal correlation between GC pauses and p99 latency, including whether the pause duration and request queueing line up. Then I would characterize the GC workload using pause distributions, allocation rate, heap occupancy, live-set behavior, CPU usage, and collector phases. I would determine whether the application is experiencing direct stop-the-world delay, secondary queue buildup, or both. Finally, I would change one relevant variable at a time and compare equivalent workload windows to verify whether the intervention improves the latency distribution.