BackendBench
Coffee
Playground

GC pause and heap generations visualizer

Allocate objects and watch eden, survivor space and the old generation fill, age and empty. Change the survival rate and tenuring threshold, simulate a leak, and compare illustrative pauses for Parallel, G1 and ZGC.

Illustrative Heap behaviour is modelled on how HotSpot works. Pause lengths are example values from simple formulas, not benchmarks.

0 MBheap used
0 MBallocated
0young GCs
0full GCs
0 msworst pause

Same heap, three collectors illustrative

Full collection pause in ms (bar length uses a square-root scale).

GC log

How a generational heap works

Most Java objects are short-lived: request objects, temporary strings, iterators. The JVM exploits that by splitting the heap into a young generation and an old generation. New objects are allocated in eden. When eden is full, a young collection finds the objects that are still reachable and copies them into a survivor space. Everything else is reclaimed without being examined, which is why young collections are quick and why allocating many short-lived objects is cheaper than it looks.

Each time an object survives a young collection its age increases. Once it passes the tenuring threshold, it is promoted to the old generation. If the survivor space is too small, objects are promoted early; this premature promotion fills old with data that dies soon after, and then only an expensive old collection can reclaim it. Raise the survival rate and lower the threshold in the playground to see old fill up faster.

Why pause time differs between collectors

Parallel GC stops every application thread and copies or compacts with several threads, so its pause grows with the live data. G1 divides the heap into regions and works in bounded increments toward a pause target. ZGC (and Shenandoah) move objects concurrently using load barriers, so the stop-the-world part is tiny. The trade-off is CPU and memory overhead rather than pause time. The numbers in this playground only illustrate those shapes. Tune for your own workload by reading real GC logs.

Reading a leak

Turn on the leak option. Objects that reach the old generation never become unreachable, so a full collection frees nothing, old stays near its limit and the JVM ends with OutOfMemoryError: Java heap space. In a real service you would see the old generation after each full GC rising run after run, then take a heap dump.

Learn the concepts

Garbage collection ยทJVM memory model ยทMemory leaks ยทWeak references ยทJVM memory calculator

Frequently asked questions

What are the young and old generations in the JVM heap?

New objects are allocated in eden. When eden fills, a young collection copies the live ones to a survivor space and discards the rest. Objects that survive enough collections are promoted to the old generation, which is collected less often. Most objects die young, so young collections are cheap.

What is the tenuring threshold?

It is the number of young collections an object must survive before it is promoted to old (-XX:MaxTenuringThreshold, at most 15). The JVM may also promote earlier if the survivor space overflows, which is called premature promotion.

How do G1 and ZGC differ in pause time?

G1 copies live objects in stop-the-world pauses sized by a pause target, so pauses grow with the amount of live data it must move. ZGC does almost all its work concurrently with the application, so pauses stay very short and nearly independent of heap size, at the cost of extra CPU and memory.

Are the pause times in this playground real?

No. They are illustrative values produced by simple formulas to show the shape: copying collectors pause longer as live data grows, and ZGC stays flat. Real pauses depend on the JDK version, hardware, heap size, object graph and flags. Measure your own application with GC logs.

How do I see GC behaviour in my own application?

Start the JVM with -Xlog:gc*:file=gc.log and read the pauses and heap sizes, or use JDK Flight Recorder. Look at pause times, how often full collections happen, and whether old generation usage keeps rising after each collection, which suggests a leak.

More tools you might need