Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Off Heap Memory

ASecurity

Memory outside the Java heap: direct `ByteBuffer` and its Cleaner-driven release, `MemorySegment` and `Arena` in the FFM API, lifetime and thread confinement, when off-heap actually pays, and diagnosing native growth no heap dump explains. Use when RSS grows while the Java heap stays flat, on `OutOfMemoryError: Direct buffer memory` or an OOMKilled container with no Java exception, when `-XX:MaxDirectMemorySize` is unset or copied from another service, when `ByteBuffer.allocateDirect` sits on...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmentrustgojavanodekubernetesgcpgitapiperformance

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill off-heap-memory --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Off Heap Memory?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Off Heap Memory
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-off-heap-memory/badge)](https://www.skillsdirectory.com/skills/robsonkades-off-heap-memory)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: off-heap-memory
description: >
  Memory outside the Java heap: direct `ByteBuffer` and its Cleaner-driven release,
  `MemorySegment` and `Arena` in the FFM API, lifetime and thread confinement, when off-heap
  actually pays, and diagnosing native growth no heap dump explains. Use when RSS grows
  while the Java heap stays flat, on `OutOfMemoryError: Direct buffer memory` or an
  OOMKilled container with no Java exception, when `-XX:MaxDirectMemorySize` is unset or
  copied from another service, when `ByteBuffer.allocateDirect` sits on a per-request path,
  when `Unsafe.allocateMemory` appears without a matching `freeMemory`, on a
  `WrongThreadException` from a segment, or on a JEP 498 `sun.misc.Unsafe` runtime warning.
  Does not cover the six-region container budget and which OOM means what
  (jvm-memory-regions), calling into native code as opposed to holding native memory
  (jni-and-ffm), or on-heap retention (heap-dump-analysis).
---

# Off-Heap Memory

## Purpose

Decide whether data belongs outside the Java heap, and find native growth that no heap dump
shows directly (heap dumps can still identify retaining wrappers). Off-heap is not faster by
definition — it is a **different memory budget with a different cost**. Heap cost depends on
allocation, representation, lifetime and collector behavior; primitive payload bytes are not
object references to scan, though storage and copying can still matter. Off-heap adds native
allocation/release and lifetime-management costs while retaining Java wrappers and bookkeeping.
Managed segments provide safety checks, while raw addresses do not.

The failure this prevents is unmanaged native growth. A direct `ByteBuffer` normally releases
through Cleaner/reference processing, so wrapper reachability affects timing. HotSpot also
accounts reservations in `Bits.reserveMemory`, enforces the direct-memory limit and may
request reference processing/GC on the slow path; it is therefore wrong to say native
pressure is invisible. The mechanism is still nondeterministic and distinct from explicit
arena ownership.

## Workflow

1. **Establish the request, runtime and available evidence.** Inspect the project's
   Java/toolchain and library versions; FFM examples require Java 22+ without an implied upgrade.
   For an API explanation or ownership review, source and focused lifecycle checks may suffice.
   For a growth incident, correlate available GC/heap, RSS/PSS, cgroup `memory.current` and
   workload evidence on one timeline. A busy heap does not exclude native growth.
2. **For an incident, classify the symptom.** `OutOfMemoryError: Direct buffer memory` names the direct-buffer
   reservation path. Exit 137 alone is consistent with SIGKILL, not proof of an OOM;
   Kubernetes `OOMKilled` adds runtime evidence of an OOM event, not its allocation owner.
   Inspect `memory.events`, pod/node events and all JVM/native domains before attributing it.
3. **For growth attribution, compare RSS/PSS, cgroup charge and used/committed heap over time.** Divergence is a
   native-residency hypothesis, not proof of a leak: allocator arenas/fragmentation, stacks,
   mapped files, page cache accounting, code and delayed uncommit can produce it.
4. **Select the next observation by suspected owner:** JMX `java.nio:type=BufferPool,name=direct` covers direct-buffer
   accounting, not arbitrary FFM/native allocations. Use NMT baselines/diffs for JVM-tracked
   categories, `/proc/<pid>/smaps_rollup`/maps for residency, and async-profiler native-memory
   recording where allocator/tool compatibility and production overhead are acceptable.
   Missing or disabled instrumentation is unknown evidence, not a zero allocation count;
   state what can be concluded and the smallest observation that would distinguish hypotheses.
5. **Size from legitimate capacity and the complete budget.** A justified capacity correction
   can mitigate an incident while attribution continues; it does not prove a leak was fixed.
   Raising `-XX:MaxDirectMemorySize` against sustained unbounded growth only defers failure.
   See `references/native-memory-diagnosis.md`.
6. **When migrating legacy code, pick the `Arena` type from the real ownership pattern**,
   not from habit — cross-thread access to a confined segment fails deterministically with
   `WrongThreadException`, while close/access races in a shared arena require coordination.
7. **Close with the decision, supporting evidence and any material uncertainty.** An adequate
   ownership/budget contract can need no change. For a claimed growth fix, repeat the relevant
   workload measurement and check that growth stopped rather than merely paused; keep an
   unexecuted validation plan distinct from an observed result.

## Rules

- Off-heap is justified when measured benefits such as I/O interoperability, deterministic bulk
  lifetime, mmap, addressability or reduced GC scanning outweigh allocation, bounds/access,
  copying, fragmentation and operational costs. Heap/TLAB allocation is often cheaper for
  small short-lived values, but benchmark the complete data path.
- Avoid one native allocation per hot-path operation unless ownership and measurements justify
  it. Prefer a library's proven bounded pool or a scoped arena; pooling adds retention,
  zeroing/data-remanence, fairness and use-after-release risks.
- Every raw `Unsafe` address needs explicit single-owner lifetime, overflow/alignment checks,
  failure-safe release and use-after-free protection. Prefer `MemorySegment` where its scoped
  lifetime and access model fit; migration is not a mechanical allocation-call replacement.
- Do not encode an ordinary Java object reference as an unmanaged native address. The GC does
  not treat it as a root or update it. Store values/IDs/handles governed by a supported JNI/FFM
  interop contract, with their reachability and lifetime explicit.
- **JEP 471/498 cover on-heap, off-heap and bimodal `sun.misc.Unsafe` memory access.**
  Object-plus-offset operations such as `compareAndSwapLong`, `objectFieldOffset`,
  `getAndAddInt` and volatile access are affected too. Migrate supported field/array access
  to `VarHandle`; use FFM for native memory. Use `varhandles-and-memory-ordering` when the
  atomicity or access-mode protocol needs a separate proof. JDK classes using `jdk.internal.misc.Unsafe`
  do not make application calls to the distinct `sun.misc.Unsafe` API exempt.
- Treat a JEP 498 warning as scheduled work, not log noise to filter. The flip from `warn`
  to `deny` must be checked on the target build; JEP 498's future schedule is not proof
  of integration in a release. JDK 25 GA source defaults to `WARN`. Exercise affected
  paths with `--sun-misc-unsafe-memory-access=deny` before upgrading.
- `MemorySegment` and `Arena` (JEP 454) have been **final since JDK 22** — no preview flags
  for FFM on 22+. Older baselines used preview APIs; other features may still require preview.
- There are **four** `Arena` factories: `ofConfined()` (single-owner thread), `ofShared()`
  (multi-thread), `ofAuto()` (GC-managed — the **non**-explicit mode;
  `close()` throws `UnsupportedOperationException`) and `global()` (process lifetime, `close()`
  also unsupported). `ofAuto()` permits an intentional reachability-managed lifetime when
  release timing is acceptable and the budget accounts for delayed reclamation; it cannot
  satisfy a deterministic release deadline.
- Accessing or closing a confined arena from another thread throws `WrongThreadException`. If
  more than one thread needs to access or close and lifetime must be explicit, choose `ofShared()` from
  creation and coordinate close against in-flight access.
- JOL measures the heap **wrapper**, never the native payload. Reading a few dozen bytes from
  `ClassLayout.parseInstance` on a 1 MB direct buffer and concluding it is cheap is the classic
  misdiagnosis here.
- NMT has no per-buffer granularity. Its categories and call-site detail cover JVM-tracked
  allocation paths, not every external allocator/mapping. Native-memory profiling can provide
  allocation stacks, but sampled/interposed coverage, frees, allocator compatibility and
  recording window bound what it proves.
- The referenced async-profiler 4.0 commands use `asprof` and the event `nativemem`, not
  `profiler.sh` or `-e malloc`. Verify other installed versions before copying commands;
  `async-profiler-advanced` owns capture-engine, permission and conversion troubleshooting.
- On the referenced HotSpot 25 GA implementation, absent `-XX:MaxDirectMemorySize` uses
  `Runtime.maxMemory()` as the direct-buffer ceiling. Derive an explicit value, if needed,
  from concurrency/capacity bounds, observed high-water marks, burst duration and the complete
  cgroup budget. No universal 1.3–1.5 multiplier establishes safety.
- A JMH `gc.alloc.rate.norm` near zero describes measured Java allocation per operation,
  not total cost. Native allocation/release is outside that metric; Java wrappers and
  reference processing can still contribute GC work. Compare the complete data path before
  claiming that off-heap reduces latency, memory use or GC cost.
- Check the arithmetic of any time-to-incident estimate first. Confusing MB/s with MB/min moves
  the estimate by a factor of 60.

## Decision and failure checklist

Apply the relevant checks to the ownership or performance claim; reuse adequate supplied
evidence. A narrow API explanation does not require a deployment or a full capture campaign.

- Define owner, maximum bytes, maximum concurrent allocations, release event and shutdown path.
- Cancellation/timeout is not proof native work stopped. Keep its allocation or pool lease
  alive until actual completion; a shared arena permits thread access, not data-race freedom.
- Specify whether data must be zeroed before reuse/release and whether untrusted sizes can drive
  allocation; use checked arithmetic and enforce per-request/per-tenant quotas.
- For changed allocation/lifetime code, exercise the relevant failure paths: allocation failure,
  partial initialization, double close, access after close, concurrent close/access,
  cancellation and shutdown as applicable to that owner.
- For attribution or budget validation, reconcile the relevant available heap/direct-pool/NMT/OS/
  cgroup signals; each observes a different set.
- For an authorized rollout, define the native-memory alert and rollback threshold. For a
  performance claim, compare relevant throughput, tail latency, RSS/PSS and GC work against
  the appropriate baseline; retain an adequate existing implementation when no change is justified.

## References

- [Native memory diagnosis](references/native-memory-diagnosis.md) — the tool-per-question
  table, the RSS-versus-heap procedure, NMT output shape and its limits, async-profiler
  commands, and the `MaxDirectMemorySize` sizing procedure. Read when native memory is growing
  and you need to find out where it went.
- [The FFM memory API](references/ffm-memory-api.md) — the four `Arena` types with their
  selection rule, `MemorySegment` and `MemoryLayout` usage, mmap through a segment, a pooling
  pattern, and the step-by-step migration from `Unsafe` or `DirectByteBuffer`. Read when
  writing or migrating off-heap allocation code.

Authoritative sources: [JEP 454](https://openjdk.org/jeps/454),
[JEP 471](https://openjdk.org/jeps/471), [JEP 498](https://openjdk.org/jeps/498),
[`Arena` API, JDK 25](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/foreign/Arena.html),
and the OpenJDK 25 GA [`Bits.reserveMemory` implementation](https://github.com/openjdk/jdk/blob/jdk-25-ga/src/java.base/share/classes/java/nio/Bits.java)
and [`sun.misc.Unsafe`](https://github.com/openjdk/jdk/blob/jdk-25-ga/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java).
The accounting distinction is visible in HotSpot 25 GA's
[primitive-array traversal](https://github.com/openjdk/jdk/blob/jdk-25-ga/src/hotspot/share/oops/typeArrayKlass.inline.hpp)
and JMH 1.37's [GC profiler](https://github.com/openjdk/jmh/blob/1.37/jmh-core/src/main/java/org/openjdk/jmh/profile/GCProfiler.java).

Attribution

robsonkadesrobsonkades
View sourceMore from robsonkades →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

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 (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →