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
  • 2 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…