How do `-gc`, `-gcutil`, and `-gccapacity` differ, and when would you reach for each?
answer
- -gcutil = percentages (used ÷ capacity)
- -gc = raw bytes: C columns = capacity, U columns = used
- -gccapacity = min/current/max sizes (MN/—/MX)
- Triage→gcutil, exact→gc, tuning→gccapacity
- OGC == OGCMX means old gen is at its ceiling
basics
~20 s-gcutil shows each region as a percentage full. -gc shows the same regions but as raw capacity and used bytes (in KB) plus GC times. -gccapacity shows the min, current, and max sizes each region is allowed to be. Use -gcutil for a quick health check, -gc for exact numbers, -gccapacity to see sizing limits.
solid answer
~40 sAll three are GC views of the same memory regions but at different abstraction levels. **`-gcutil`** is normalized to **percentages** — fastest to eyeball for 'how full and how much GC.' **`-gc`** gives the **raw bytes**: for each region it prints capacity (e.g. EC) and used (e.g. EU) in kilobytes, plus the GC counts/times — useful when you need exact figures, to compute headroom, or to feed a script. **`-gccapacity`** focuses on **sizing limits**: the minimum, current, and maximum capacity each region (new, old, metaspace) can take, which is what you check when tuning `-Xms/-Xmx`, `-Xmn`, or metaspace flags, because it shows whether a region has already grown to its ceiling. Rule of thumb: triage with -gcutil, get exact used/free with -gc, and verify growth limits with -gccapacity.
go deeper
Knows -gcutil is the percentage view and that -gc/-gccapacity exist with more detail, even if hazy on exact columns.
Distinguishes percentage (-gcutil) vs raw bytes (-gc) vs size limits (-gccapacity) and picks the right one for triage vs tuning.
Reads C/U/MN/MX column conventions fluently, computes free bytes and ceiling-hits, and connects them to -Xmx/-Xmn/MaxMetaspaceSize tuning.
Uses these views to set heap-sizing policy across services and knows when ad-hoc jstat sampling should give way to continuous GC logging/JFR for decisions.
## Three GC views, same regions jstat exposes the JVM's garbage-collection statistics through several `-gc*` options. The three you reach for most often — `-gcutil`, `-gc`, and `-gccapacity` — describe the **same memory regions** (eden, survivors, old, metaspace) but answer different questions. ### Background: capacity vs used vs limit For any memory region the JVM tracks three distinct quantities: - **Used** — how many bytes currently hold live data. - **Capacity** (current size) — how big the region is *right now*; the JVM can grow or shrink it between its min and max. - **Max / min** — the bounds the region is allowed to grow/shrink to (driven by flags like `-Xmx`, `-Xmn`, `-XX:MaxMetaspaceSize`). The three options each emphasize a different pair of these. ### `-gcutil` — percentages (used ÷ current capacity) Columns are **S0 S1 E O M CCS YGC YGCT FGC FGCT GCT**, with the region columns expressed as a **percentage** (used / current capacity × 100). This is the quickest human read: "eden 61% full, old 45% full, 2 full GCs." You lose the absolute scale, but for a health check that's fine. ### `-gc` — raw bytes (used and capacity) Columns expand each region into a **capacity** and a **used** value in **kilobytes**, e.g.: - **S0C / S1C** survivor capacities, **S0U / S1U** survivor used - **EC / EU** eden capacity / used - **OC / OU** old capacity / used - **MC / MU** metaspace capacity / used, **CCSC / CCSU** compressed-class capacity/used - plus **YGC YGCT FGC FGCT GCT** (same GC counters) Use `-gc` when you need **exact numbers**: to compute free bytes (capacity − used), to see how close used is to capacity, or because a script needs machine-parseable absolute values rather than percentages. ### `-gccapacity` — sizing limits (min / current / max) This view drops the 'used' detail and instead shows, per region group, the **minimum, current, and maximum** capacity: - **NGCMN / NGCMX / NGC** — new (young) generation min / max / current - **OGCMN / OGCMX / OGC** — old generation min / max / current - **MCMN / MCMX / MC** — metaspace min / max / current - plus current eden/survivor capacities and the GC counts This is the **tuning** view. It answers: *has a region already grown to its ceiling?* If `OGC` equals `OGCMX`, the old generation can't expand further — under pressure that means more frequent full GCs or an eventual OOM, so you'd raise `-Xmx`. If metaspace `MC` is pinned at `MCMX`, raise `MaxMetaspaceSize` or hunt a classloader leak. ### Choosing between them | Question | Option | |---|---| | "Is the app under GC pressure right now?" (quick eyeball) | `-gcutil` | | "Exactly how many bytes are used/free in old gen?" | `-gc` | | "Has a region hit its max size? Are my -Xmx/-Xmn limits right?" | `-gccapacity` | In practice you start with `-gcutil` for triage, switch to `-gc` when you need precise figures or to script, and consult `-gccapacity` when you move from *observing* to *tuning* heap sizes. There are further specializations — `-gcnew`/`-gcnewcapacity` and `-gcold`/`-gcoldcapacity` — that apply the same used-vs-limit split to a single generation.
- In `-gc` output, what's the difference between EC and EU?EC is Eden Capacity — the current size of the eden space in kilobytes — and EU is Eden Used — how many of those kilobytes currently hold live data. Free eden is EC − EU. The same C/U suffix convention applies to survivors (S0C/S0U), old (OC/OU), and metaspace (MC/MU).
- How would `-gccapacity` help you decide to raise -Xmx?If OGC (current old-gen capacity) has already reached OGCMX (its maximum) while the app still suffers frequent full GCs, the old generation is at its ceiling and can't grow to absorb live data. That's a strong signal to raise the max heap (-Xmx) — or, if it's a leak, to fix the leak rather than just enlarging the heap.
saying these in an interview costs you the question
- Thinking the three options report different metrics rather than different views of the same regions
- Assuming -gc values are in bytes — they are in kilobytes
- Using -gcutil to make sizing decisions when you really need the absolute limits from -gccapacity
- Confusing 'used' (U columns) with 'capacity' (C columns) in -gc output