Skip to content
Back to skills

Zgc Generational Internals

ASecurity

Generational ZGC internals: coloured pointers without multi-mapping, the load and store barriers, the young and old cycles and their STW phases, the remembered-set bitmap and its double buffering, relocation and page management, allocation stalls, and the generational log and JFR event names. Use when a deploy script still carries -XX:+ZGenerational, when jdk.ZAllocationStall events appear or allocation stalls cluster in traffic peaks, when a pause script greps only "Pause Mark" and reports a...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
developmentgogitperformance

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 29, 2026

npx -y skills add robsonkades/agent-skills --skill zgc-generational-internals --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Zgc Generational Internals?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Zgc Generational Internals
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-zgc-generational-internals/badge)](https://www.skillsdirectory.com/skills/robsonkades-zgc-generational-internals)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: zgc-generational-internals
description: >
  Generational ZGC internals: coloured pointers without multi-mapping, the load and store
  barriers, the young and old cycles and their STW phases, the remembered-set bitmap
  and its double buffering, relocation and page management, allocation stalls, and the
  generational log and JFR event names. Use when a deploy script still carries
  -XX:+ZGenerational, when jdk.ZAllocationStall events appear or allocation stalls cluster
  in traffic peaks, when a pause script greps only "Pause Mark" and reports a suspiciously
  good p99, when heap sizing was carried over unchanged from G1, when ZGC thread CPU is
  being read out of a thread dump, or when barrier overhead needs to be attributed to reads
  versus writes. Does not cover choosing between or operating the concurrent collectors
  (zgc-and-shenandoah), the introductory collector model (gc-fundamentals), or attributing
  an observed production pause across layers (pause-attribution).
---

# ZGC Generational Internals

## Purpose

Decide what a generational ZGC symptom is actually caused by — barrier cost, heap headroom,
promotion rate, or a measurement that never looked at the right phase — using the mechanism
rather than a remembered flag list. On JDK 25 there is no non-generational mode to compare
against, so the generational behaviour _is_ ZGC behaviour. Establish the actual implementation
and evidence before selecting a change; a collector regression remains a candidate when supported.

The failure this prevents is the confident no-op: reasserting a flag that was removed or is
already the default, copying a heap multiplier from another service, or reporting a pause
percentile computed from a log grep that misses one of the three STW phases. Each of these
leaves the real problem undiagnosed while looking like a fix.

## Workflow

Use the steps needed for the requested mechanism, parser or operational claim. Reuse adequate
source, captures and configuration; a narrow explanation or supported no-change conclusion does
not require a new logging, profiling or load campaign. Inspect the target vendor/build, OS/architecture
and effective collector support; JDK 25 HotSpot is the source baseline, not authorization to upgrade.

1. **Establish the baseline before anything else.** `-XX:+UseZGC` alone is generational on
   JDK 25. Confirm ZGC is actually selected in successful `jcmd <pid> VM.flags -all` output
   or adequate startup evidence — not merely that a mode flag is present. Preserve producer failures
   before filtering; unavailable flags are not evidence that an option is false or absent.
2. **Read the flags off the running JVM, not from memory.** Check `ZCollectionInterval`,
   `ZAllocationSpikeTolerance` and `ZProactive` with `-XX:+PrintFlagsFinal` or
   `jcmd <pid> VM.flags -all` against the build in use; these defaults move between releases.
3. **For a complete pause-population claim, capture every relevant STW phase.** Log with
   `-Xlog:gc*,gc+phases=debug`; validate the parser against real young and old cycles and do
   not assume one textual phase list survives releases.
4. **Separate young and old-cycle evidence.** Frequency is workload/ergonomic, not “continuous
   versus rare.” Correlate promotion/aging, live bytes, allocation and old-cycle triggers;
   temporal overlap alone does not prove promotion pressure.
5. **Classify allocation stalls from relevant capacity signals.** Correlate available stall intervals with free/used/soft-max
   heap, live set, page/large allocation, concurrent-cycle progress, allocation rate,
   `ConcGCThreads`, CPU throttling and safepoints. Time-of-day clustering is context, not cause.
6. **Attribute barrier cost from generated code/profile evidence.** Fast paths are commonly
   inlined and may not appear as named frames. Stores execute a barrier path broadly; only
   some require remembered-set work. See `references/barriers-and-remembered-set.md`.
7. **Choose remediation from supported constraints and hypotheses:** reduce allocation/live set, restore CPU,
   add justified hard/soft heap headroom, control bursts/backpressure, or run a scoped
   heuristic experiment. There is no safe global order of flags. An authorized bounded mitigation
   can precede complete causal attribution; state the uncertainty and verify its relevant outcomes.

## Rules

- Do not add `ZGenerational` to JDK 24+: JEP 490 made it obsolete, with a warning while
  ignoring the value. Reproduced on Temurin 25.0.3+9. Expiration subsequently makes it
  unrecognized; test the exact upgrade build rather than treating acceptance as application.
  Historical JDK 21/22 generational selection requires the version-specific flag.
  Timeline: JEP 439 (JDK 21, opt-in) → JEP 474 (JDK 23, default) → JEP 490 (JDK 24, only mode).
- Reasserting default-enabled `ZProactive` is not an allocation-stall fix. Inspect its
  effective value and cycle trigger before considering a change; proactive collection
  uses build-specific growth/time and estimated collection-cost conditions, not merely an idle-state
  test, and does not guarantee recovery from sustained peaks.
- Heap sizing is conditional on measured live set, allocation distribution, relocation
  progress, large pages/objects, concurrent CPU and burst duration. No collector-independent
  live-set multiplier (1.5×, 2.5× or 4×) predicts safety; derive and validate headroom under
  the steady, peak or throttled conditions relevant to the sizing claim.
- A pause script that greps `"Pause Mark"` reports an incomplete population —
  `Pause Relocate Start` is a real STW pause and is commonly omitted from diagrams. Every
  such script must distinguish failed/missing capture from a successful empty population. With
  adequate configuration/window evidence, report zero observed pauses and an undefined percentile;
  zero samples never establish p99=0.
  Omitting a phase can bias a percentile either way. Allocation stalls block allocating
  threads, not necessarily all application threads at a global safepoint; keep them separate.
- The load-barrier fast path checks collector metadata in **the pointer value** before any
  access to the pointed-to object. The emitted check depends on architecture/compiler/access
  kind; do not require a standalone mask instruction. Any explanation shaped like
  `if (obj.color != expected)` inverts the dependency order that makes the mechanism safe.
- An object's generation is represented in `ZPage` metadata on the inspected JDK 25 source,
  not inferred from a simple generation color in each oop. Pointer metadata and barrier masks
  evolve; quote exact bits only from the target source/build.
- The remembered set is a **bitmap** (`ZRememberedSet` in `zRememberedSet.hpp`) with one bit per
  potential object-field address — not G1's byte-per-card array. Do not describe it as a
  card table.
- Legacy ZGC multi-mapping and JEP 490's removal of non-generational mode are distinct
  changes. Never infer cgroup charge from old `ps` folklore; measure RSS/PSS, heap and
  `memory.current` on the target build.
- Confirm ZGC JFR events with `jfr metadata`. JDK 25 includes the young/old/stall/page events
  plus relocation-set, statistics, thread-phase and uncommit events. There is no
  `jdk.ZGCGarbageCollection` on that build, but do not turn this list into a cross-release
  allowlist.
- `jcmd <pid> Thread.dump` is not a subcommand. Use `Thread.print` or
  `Thread.dump_to_file -format=json` — and neither measures CPU. For per-thread CPU use
  `top -H -p <pid>` or `pidstat -t -p <pid> 1`.
- Distinguish measured overhead/sizing evidence from estimates. Report an actual measurement
  with its build, workload and method; label unmeasured predictions as conditional.

## Validation for the intended claim

- For complete-population results, reconcile counts with actual cycle IDs/generations and verify
  phase names, complete rotated inputs and recording loss. An independently verified subset may
  still support an explicitly limited result; do not label it the whole window or a perfect percentile.
- For a sizing or stall-remediation decision, exercise relevant allocation/live-set, large-object,
  CPU quota or soft-target conditions that the evidence does not already cover. Keep tests within
  authorized operational bounds and verify stalls, achieved throughput and memory headroom together.
- For a performance claim about a barrier/flag change, preserve relevant correctness tests
  and compare the affected CPU, allocation, throughput or tail-latency outcomes across
  representative repeated runs on the exact JDK build. Flag acceptance alone proves no gain.

## References

- [Cycles, logs and events](references/cycles-logs-and-events.md) — the phase sequence with
  STW phase families, the per-generation log format, the JFR event table and the recording
  and reading commands. Read when configuring ZGC logging, writing a pause-measurement
  script, or interpreting a generational ZGC log.
- [Barriers and the remembered set](references/barriers-and-remembered-set.md) — the load and
  store barrier fast paths, the remembered-set bitmap, its double buffering, and how to
  attribute barrier cost in a profile. Read when barrier overhead is suspected, when
  promotion rate is in question, or when documenting the mechanism internally.

Authoritative sources: [JEP 439](https://openjdk.org/jeps/439),
[JEP 474](https://openjdk.org/jeps/474), [JEP 490](https://openjdk.org/jeps/490), and the
[OpenJDK 25 ZGC sources](https://github.com/openjdk/jdk/tree/jdk-25-ga/src/hotspot/share/gc/z).

Files in this skill

  • SKILL.md9.3 KB
  • references/barriers-and-remembered-set.md9.1 KB
  • references/cycles-logs-and-events.md12.2 KB
  • skill.yaml1.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.