Skip to content
Back to skills

Jvm Memory Regions

ASecurity

The major memory-accounting domains of a JVM process — heap, Metaspace/class space, code cache, thread stacks, direct/native/JVM-internal memory and mapped/file-backed pages — and how to budget them against a container limit. Use when a pod is OOMKilled with no Java exception, when an OutOfMemoryError names something other than "Java heap space", when -Xmx is set equal to the container limit, when RSS exceeds the heap by more than expected, when a heap above 32 GB is proposed, or when sizing ...

  • 2 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 19, 2026
developmentgojavaexpresskubernetestestinggit

Works with

  • cli

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 jvm-memory-regions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Jvm Memory Regions?

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

Security grade badge for Jvm Memory Regions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-jvm-memory-regions/badge)](https://www.skillsdirectory.com/skills/robsonkades-jvm-memory-regions)

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: jvm-memory-regions
description: >
  The major memory-accounting domains of a JVM process — heap, Metaspace/class space, code
  cache, thread stacks, direct/native/JVM-internal memory and mapped/file-backed pages — and
  how to budget them against a container limit.
  Use when a pod is OOMKilled with no Java exception, when an OutOfMemoryError names
  something other than "Java heap space", when -Xmx is set equal to the container limit,
  when RSS exceeds the heap by more than expected, when a heap above 32 GB is proposed, or
  when sizing a JVM for Kubernetes. Does not cover collector choice and heap tuning
  (jvm-gc-tuning), classloader leaks (jvm-class-loading), or kernel-side memory behaviour
  such as page faults, swap and the OOM killer (linux-for-jvm). Metaspace internals are
  metaspace-internals, memory outside the heap is off-heap-memory, and heap contents are
  heap-dump-analysis.
---

# JVM Memory Regions

## Purpose

Budget a JVM process against a hard memory limit. A common failure is `-Xmx` set to the
container limit, with non-heap
regions pushing RSS past the cgroup, and the **kernel** killing the process — no
`OutOfMemoryError`, no shutdown hook, no heap dump, because the JVM never knew it was
dying.

Only the Java heap object graph is reclaimed directly as ordinary GC-managed objects, but
class unloading, code-cache reclamation, native cleaners/arenas and OS reclaim couple the
other domains to different lifecycles. Not every domain has a hard flag or a distinct
`OutOfMemoryError`; that is why accounting starts from evidence rather than six fixed boxes.

Inspect the target JDK/vendor/update, collector, effective flags, OS and cgroup hierarchy
before applying a budget. JDK 25 examples describe one HotSpot environment; neither a newer
feature nor a measurement here authorizes changing the project's runtime.

## Workflow

Start from the requested decision and available deployment, runtime and workload evidence. A
flag explanation does not require a new recording, and a sound existing budget need not change.
Use the relevant steps below; a sizing request without a failure needs capacity evidence rather
than an invented OOM diagnosis. Treat an unknown limit or unobserved peak as an assumption to
resolve, not a measured value. Changes or restarts must fit the already authorized action scope.

1. **For a failure, read the full OOM message first.** It suggests an allocation path or resource limit, not necessarily
   the root cause; preserve causes and external process/container evidence. `Metaspace`, `Direct buffer memory` and `unable to create native
thread` require different evidence; raising `-Xmx` is not a general repair and can increase
   native/cgroup pressure even when it also raises an implicit direct-buffer limit.
2. **Measure JVM-tracked non-heap with NMT under your own load**, and model untracked domains:
   `-XX:NativeMemoryTracking=summary` at start, then
   `jcmd <pid> VM.native_memory summary`; `baseline` followed later by `summary.diff`
   attributes tracked growth to a category. Periodic JFR NMT/RSS events can provide a
   related time series when present/enabled, but do not assume identical semantics. The NMT
   events also require NMT enabled at startup; starting JFR later cannot recover that missing
   attribution. NMT cannot be enabled on a running process. When it is absent, use existing
   metrics/maps and retain the attribution gap; restarting solely to complete this workflow
   is not required. Near a hard limit, diagnostic clients and extra JVM probes consume scarce
   capacity too; prefer existing telemetry and bounded OS reads until their overhead fits the budget.
3. **Budget every region and peak overlap**: candidate heap max = limit − measured/modelled
   non-heap/cgroup peaks − uncertainty/recovery headroom. Then express it as `-Xmx` or
   `MaxRAMPercentage` against the memory value the JVM actually detected, and verify the
   resulting `MaxHeapSize`: small-memory ergonomics and alignment can change the percentage result;
   the arithmetic and the RSS-versus-NMT gap table are in
   `references/container-budget.md`.
4. **Distinguish virtual reserved, NMT committed, resident and cgroup-charged.** `ps` exposes
   both VSZ and RSS; neither is identical to NMT totals or `memory.current`. A residual
   obtained by subtracting NMT committed from RSS is not a measured untracked-native total.
5. **Judge normalized trends, not instants** — compare equivalent reclamation points,
   native/RSS/cgroup peaks and the workload regime that produced them.
6. **Deliver a bounded decision.** State observed attribution, competing explanations,
   the candidate budget or evidence for keeping the current settings, and material unknowns.
   Separate proposed effects from validated results; name the next discriminating check or
   rollout measurement. Missing NMT/maps or peak-overlap evidence remains a limitation.

## Rules

- Choose fixed versus variable initial heap from startup, RSS/density, idle-uncommit and SLO
  measurements. `-Xms = -Xmx` removes heap growth but is not a universal production rule.
- Set `MaxMetaspaceSize` only as a deliberate fail-fast/capacity boundary. Too low causes
  avoidable OOM during legitimate class loading; absent/unbounded shifts the boundary to
  process/cgroup capacity. Alert on class-loader/class-space trends either way.
- `unable to create native thread` can mean PID/rlimit exhaustion, native allocation
  failure, cgroup pressure or virtual-address constraints. Changing `-Xmx` helps only when
  measured heap commitment/residency is consuming the relevant resource; it can also hide
  the real PID/thread-lifecycle defect.
- The compressed-oop cutoff for applicable HotSpot collectors is often near 32 GiB but
  depends on alignment, heap base/reservation and build. Confirm effective flags/layout;
  ZGC's colored-pointer scheme is not a compressed-oops workaround.
- `-Xss × platform-thread count` is only an approximate Java-stack reservation model,
  not a process-wide bound or resident bytes. JVM/native threads, main-thread policy,
  rounding and guard regions can differ; inspect actual reservations. Reduce stacks only after testing Java/native call depth and guard-page behavior;
  stack overflow is a correctness failure, not merely a tuning regression.
- Code-cache pressure can stop compilation and trigger reclamation/restart behavior
  that varies by tier/segment and release. `jdk.CodeCacheFull` is strong evidence of an
  event, not proof of permanent interpretation or a universal 80% threshold. Correlate
  compiler logs, segment occupancy, reclamation and throughput (`code-cache-segments`).
  HotSpot removed the sweeper in JDK 20; on the JDK 25 baseline, do not require a sweeper
  thread or its old lifecycle states as evidence.
- Measure object layout with JOL rather than estimating headers. Compact object headers
  (JEP 519, product in 25) are **off by default through JDK 26 and on by default from
  JDK 27** (JEP 534); confirm the effective setting on the target build. Disable with
  `-XX:-UseCompactObjectHeaders`. **Do not budget 8 bytes
  per object**: alignment makes savings class/layout-dependent, and some common small
  objects can retain the same aligned size while their surrounding graph/arrays change.
  For the rule that predicts which classes do save, the measured
  per-class table and the per-object arithmetic, see `object-layout-and-footprint`.
- Unmounted virtual-thread continuation chunks live in the heap, while mounted execution
  uses carrier/native stack state. Millions of tasks can therefore shift context/stack
  retention into GC-visible objects; measure mounted/unmounted state and in-flight
  concurrency before adjusting heap or `-Xss`.
- `MaxDirectMemorySize` is a separate ceiling. On the verified HotSpot implementation its
  absent value resolves to `Runtime.maxMemory()`, so choosing a large `-Xmx` can implicitly
  authorize a similarly large direct-buffer budget; it does not reserve that memory or make
  the combined process fit.

## Evidence and rollout safety

- Capture NMT, process maps, cgroup files and JFR at aligned timestamps with JDK vendor/
  update, PID, container ID and load. “Committed,” RSS/PSS and `memory.current` must never
  be joined from different windows as if simultaneous.
- Process maps, hs_err, heap/core dumps and command lines can expose paths, credentials and
  payloads. Restrict collection/transfer, redact only on a preserved copy, record hashes and
  expire artifacts under incident policy.
- For any limit/heap/stack/metaspace change, canary with abort thresholds for OOM kills,
  Java OOMs, startup time, RSS/cgroup high-water mark, faults, GC tails, throughput and
  stack overflow. Retain the previous configuration for rollback.

## References

- [Container budget](references/container-budget.md) — the per-region budget with the
  worked `MaxRAMPercentage` arithmetic, reading `VM.native_memory summary` and `diff`,
  the RSS-versus-NMT gap table, and the Kubernetes checklist. Read when sizing a JVM for
  a memory limit or when RSS does not match the heap.
- [OOM triage by region](references/oom-triage.md) — which message means which region,
  the `jcmd` command that confirms each, what does _not_ fix it, and the
  `ExitOnOutOfMemoryError` / `CrashOnOutOfMemoryError` decision. Read when an
  `OutOfMemoryError` or an OOMKill has already happened, or when configuring what the JVM
  does on the next one.

Authoritative sources: [Oracle Native Memory Tracking guide](https://docs.oracle.com/en/java/javase/25/vm/native-memory-tracking.html),
[Oracle container support guide](https://docs.oracle.com/en/java/javase/25/docs/specs/man/java.html#java-options-for-linux),
[JEP 519](https://openjdk.org/jeps/519), [JEP 534](https://openjdk.org/jeps/534),
[JDK 27 release notes](https://www.oracle.com/java/technologies/javase/27all-relnotes.html),
[HotSpot sweeper removal, JDK-8290025](https://bugs.openjdk.org/browse/JDK-8290025), and the
[Linux cgroup v2 memory controller](https://docs.kernel.org/admin-guide/cgroup-v2.html#memory).

Files in this skill

  • SKILL.md8.8 KB
  • references/container-budget.md15.4 KB
  • references/oom-triage.md11.8 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.