skip to content

Java Memory APIs & Diagnostics

The Java-level memory APIs and diagnostics that sit on top of the JVM: soft, weak and phantom references, ReferenceQueue and Cleaner, the OutOfMemoryError and StackOverflowError families, classic leak patterns, and the tooling to find them. Senior interviews almost always include a production memory-problem scenario, and this is the vocabulary for answering it.

part ofJavaoverview, primer and where to startread it →
on this pageshow

explore

questions

page 1 of 2

What are the main runtime memory areas the JVM divides memory into, and which are shared across threads versus per-thread?

level: juniorimportance: must knowfreq 72%

answer

  1. Heap = shared, objects; Stack = per-thread, frames
  2. Metaspace = class metadata, native memory, replaced PermGen in Java 8
  3. PC register + native stack also per-thread
  4. OOM: heap space vs Metaspace; StackOverflow vs OutOfMemory

basics

~20 s

The JVM splits memory into the heap (where objects live, shared by all threads), the stacks (one per thread, holding method calls and local variables), and metaspace (class metadata). The heap is where garbage collection happens.

solid answer

~40 s

The JVM organizes memory into a few runtime data areas. The heap is a single shared region where all objects and arrays are allocated and where the garbage collector operates; modern HotSpot splits it into generations (young + old). Each thread gets its own JVM stack, made of frames pushed per method call, holding local variables, operand stack, and the return address; this is where StackOverflowError comes from. The program counter (PC) register is also per-thread, tracking the current bytecode instruction. Metaspace (native memory, since Java 8 replacing PermGen) holds class metadata such as method bytecode and field layouts. There is also a native method stack for JNI calls. The key split: heap and metaspace are shared; stacks and PC registers are per-thread, which is why thread-local data needs no synchronization.

go deeper

for a junior

Can name heap (objects), stack (method calls/locals), and that the heap is where GC works; knows objects go on the heap.

for a middle

Explains the shared-vs-per-thread split, what a stack frame holds, and distinguishes StackOverflowError from OutOfMemoryError with their causes.

for a senior

Adds Metaspace vs PermGen history, generational heap layout, PC register and native stack, and ties the split to why local data needs no synchronization.

for a principal

Reasons about sizing (heap, Metaspace, thread-stack -Xss) trade-offs, off-heap memory, classloader leaks filling Metaspace, and how memory-area layout informs container memory limits and OOM diagnostics.

## What "runtime memory areas" means The **JVM (Java Virtual Machine)** is the runtime that executes your compiled Java (bytecode). When it runs, it carves the memory the operating system gives it into distinct **runtime data areas**, each with a specific job. Knowing these areas explains where objects live, why some errors happen, and how garbage collection works. ## The areas, one by one ### 1. Heap (shared) The **heap** is one big region shared by every thread. **Every object and array you create with `new` lives here.** Because it is shared, two threads can both reference the same object — which is exactly why you need synchronization for shared mutable state. The heap is the *only* area the **garbage collector (GC)** manages: GC is the automatic process that reclaims memory of objects no longer in use. HotSpot (the standard JVM) further divides the heap into **generations** — a **young generation** for newly created, short-lived objects, and an **old (tenured) generation** for objects that survive long enough. Running out of heap throws `OutOfMemoryError: Java heap space`. ### 2. JVM stacks (per-thread) Each thread has its **own stack**. Every time a method is called, a **stack frame** is pushed onto that thread's stack; when the method returns, the frame is popped. A frame holds: - **Local variables** (including method parameters and `this`), - The **operand stack** (scratch space the bytecode uses to compute expressions), - A reference to the constant pool / return information. Important: a frame stores **primitives by value** and **objects by reference** (the object itself is on the heap; only the pointer is on the stack). Because each thread has its own stack, stack data is implicitly thread-safe. Infinite or too-deep recursion exhausts the stack → `StackOverflowError`. ### 3. Program Counter (PC) register (per-thread) A tiny per-thread register holding the address of the **bytecode instruction currently executing**. It lets the JVM resume the right spot after a thread is paused. ### 4. Metaspace (shared, native memory) **Metaspace** stores **class metadata**: the loaded class's structure — its methods' bytecode, field names and types, the runtime constant pool, etc. It is *not* the heap; it lives in **native (off-heap) memory** sized by the OS. Before Java 8 this was the fixed-size **PermGen (Permanent Generation)**, which was a frequent source of `OutOfMemoryError: PermGen space`. Java 8 replaced it with Metaspace, which auto-grows (bounded by `-XX:MaxMetaspaceSize`); exhausting it throws `OutOfMemoryError: Metaspace`. ### 5. Native method stack (per-thread) Used when Java calls **native (C/C++) code** via **JNI (Java Native Interface)**. ## The shared-vs-per-thread split (the headline) | Area | Scope | Holds | |---|---|---| | Heap | **Shared** | objects, arrays | | Metaspace | **Shared** | class metadata | | JVM stack | **Per-thread** | frames: locals, operand stack | | PC register | **Per-thread** | current instruction | | Native stack | **Per-thread** | native-call state | This split is the whole reason **local variables never need locking but heap objects do**. ## Why this matters for the Java APIs in this topic Reference types (`SoftReference`/`WeakReference`/`PhantomReference`), `Cleaner`, and `OutOfMemoryError` diagnostics all operate on **heap** objects and the GC that manages them. You cannot reason about "will this object be collected" without knowing it lives on the shared heap and is reached (or not) from thread stacks and static fields — the **GC roots**.

  • Why was PermGen replaced by Metaspace in Java 8?
    PermGen had a fixed, hard-to-size limit living in the heap, causing frequent OutOfMemoryError: PermGen space (especially with many classloaders/redeploys). Metaspace moves class metadata to auto-growing native memory, removing the fixed cap by default and tying it to OS memory instead.
  • Where does a local primitive int versus a local object reference get stored?
    Both sit in the current stack frame's local-variable slots. The int's value is stored inline; for an object, only the reference (pointer) is in the frame — the object itself is allocated on the heap.

saying these in an interview costs you the question

  • Saying objects live on the stack — only references/primitives sit in frames; objects are on the heap
  • Calling Metaspace part of the heap (it is off-heap native memory)
  • Thinking each thread has its own heap
  • Confusing StackOverflowError (stack exhausted) with OutOfMemoryError (heap/metaspace exhausted)

context

open as a page

What is a heap dump, and what are the main ways to capture one from a running or crashing JVM?

level: juniorimportance: must knowfreq 62%

basics

~20 s

A heap dump is a snapshot of all objects in the JVM heap at one moment, saved to a file. You can trigger it on demand with jmap, or have the JVM write one automatically when it runs out of memory using the -XX:+HeapDumpOnOutOfMemoryError flag.

open as a page

Java has a garbage collector, so how can a Java program still leak memory?

level: juniorimportance: must knowfreq 70%

basics

~20 s

The garbage collector only frees objects nothing else points to. If your code keeps a reference to an object you no longer use, the collector cannot free it. The memory is still 'reachable', just wasted. That is a Java memory leak.

open as a page

What is an OutOfMemoryError in Java, why is it an Error rather than an Exception, and should you catch it?

level: juniorimportance: must knowfreq 70%

basics

~20 s

OutOfMemoryError means the JVM ran out of memory and could not get more, so it can't keep running normally. It's an Error, not a regular Exception, because it signals a serious problem you usually can't recover from. Don't catch it to keep going; fix the root cause instead.

open as a page

What is a SoftReference in Java, and when does the garbage collector clear one?

level: juniorimportance: must knowfreq 55%

basics

~10 s

A SoftReference is a special wrapper around an object that lets the garbage collector throw that object away, but only when the JVM is running low on memory. Until then, the object stays alive.

open as a page

What is a StackOverflowError in Java, and what most commonly causes it?

level: juniorimportance: must knowfreq 70%

basics

~20 s

It is an error thrown when a thread runs out of stack space. The usual cause is recursion that never stops because it is missing a base case, so methods keep calling themselves until the stack fills up.

open as a page

What is a strong reference in Java, and how does it affect whether an object can be garbage collected?

level: juniorimportance: must knowfreq 70%

basics

~20 s

A strong reference is an ordinary variable that points to an object, like String s = new String(). As long as such a reference exists and can be reached by the program, the garbage collector will never delete that object.

open as a page

How does the JVM decide an object is garbage? Explain reachability and GC roots.

level: middleimportance: must knowfreq 78%

basics

~20 s

An object is garbage when it can no longer be reached by following references from "GC roots" (like local variables and static fields). The collector keeps reachable objects and frees the rest. It is not based on reference counting.

open as a page

Why are unbounded static collections and caches a classic Java memory leak, and how do you prevent them?

level: middleimportance: must knowfreq 68%

basics

~20 s

A static collection lives for the whole program and is a GC root, so anything you put in it stays in memory forever unless you remove it. If you keep adding and never evicting, the heap grows without bound. Fix it by bounding the size or evicting old entries.

open as a page

Given an OutOfMemoryError in production, how do you read the message to identify the variant and choose the right first remediation for each?

level: middleimportance: must knowfreq 68%

basics

~30 s

Read the text right after 'OutOfMemoryError:'. 'Java heap space' means object memory is full — take a heap dump and check for a leak vs. a too-small heap. 'Metaspace' means too many classes are loaded — look for a classloader leak or raise MaxMetaspaceSize. 'GC overhead limit exceeded' means the collector is thrashing — treat it like a heap problem. The message names the region; that tells you where to look.

open as a page

What does 'OutOfMemoryError: Java heap space' mean, what are its common causes, and what is your first remediation step?

level: middleimportance: must knowfreq 78%

basics

~20 s

It means the heap — the area where Java objects live — is full and the garbage collector can't free enough room for a new object. Common causes are a memory leak, a heap that's simply too small for the workload, or trying to load too much data at once. First step: capture a heap dump and check whether it's a leak or just under-sizing.

open as a page

Contrast SoftReference and WeakReference: how do their clearing policies differ, and which fits a memory-sensitive cache versus a WeakHashMap-style side table?

level: middleimportance: must knowfreq 60%

basics

~20 s

A weak reference is thrown away as soon as the next garbage collection runs once nothing else points to the object. A soft reference is kept longer — the collector only clears it when memory is running low. So soft is for caches you want to keep; weak is for cleanup that should happen quickly.

open as a page

How does StackOverflowError differ from OutOfMemoryError, and how do you tell which one you are facing?

level: middleimportance: must knowfreq 62%

basics

~10 s

StackOverflowError means one thread ran out of stack space, usually from deep recursion. OutOfMemoryError means the heap (or metaspace) is full, usually from too many or too-large objects. Different memory areas, different causes.

open as a page

How does a strong reference differ from soft, weak, and phantom references in terms of when the garbage collector may reclaim the referent?

level: middleimportance: must knowfreq 62%

basics

~20 s

A strong reference keeps an object alive as long as it is reachable. Soft references are cleared only under memory pressure, weak references at the next GC once no strong refs remain, and phantom references are used only for post-cleanup notification.

open as a page

Compare weak and soft references: when is each cleared, and which would you pick for a memory-sensitive cache?

level: middleimportance: must knowfreq 60%

basics

~20 s

Weak references are dropped at the next garbage collection as soon as nothing else needs the object. Soft references are kept as long as possible and only dropped when the JVM is running out of memory. For a cache that should survive until memory is tight, use soft references.

open as a page

Explain the reference chain that keeps a classloader alive, and why a leak is 'all-or-nothing' for its classes.

level: seniorimportance: must knowfreq 40%

basics

~20 s

Every object points to its Class, every Class points to the classloader that loaded it, and the classloader points to all the classes it loaded. So holding one live object keeps the loader and every class it loaded alive in metaspace — you can't lose just part of it.

open as a page

When analyzing a heap dump, what is the difference between shallow size and retained size, and how does a dominator tree help you find a leak?

level: seniorimportance: must knowfreq 58%

basics

~20 s

Shallow size is the memory one object uses by itself. Retained size is all the memory that would be freed if that object were removed — the object plus everything only it keeps alive. A dominator tree shows which objects hold the most memory, so you look at the biggest retained sizes to find the leak.

open as a page

Compare strong, soft, weak, and phantom references in terms of when the GC clears them and what each is for.

level: juniorimportance: should knowfreq 45%

basics

~20 s

Strong references are normal references and stop collection. Soft references are cleared only when memory is low (caches). Weak references are cleared as soon as nothing strong points to the object (canonical maps). Phantom references are the weakest and only signal that the object was already collected (cleanup).

open as a page

Explain generational garbage collection and the weak generational hypothesis. How do minor and major collections differ?

level: middleimportance: should knowfreq 66%

basics

~20 s

Most objects die young, so the heap is split into a young generation (new objects) and an old generation (survivors). A minor GC collects only the young area (fast, frequent); a major/full GC handles the old area (slower, rarer). Objects that survive get promoted to the old generation.

open as a page

How would you diagnose and confirm a classloader leak in a running JVM?

level: middleimportance: should knowfreq 35%

basics

~20 s

Watch metaspace climb with each redeploy and never fall, ending in OutOfMemoryError: Metaspace. Then take a heap dump, find the classloaders that should be dead, and use the tool's 'path to GC roots' to see which reference is keeping each one alive.

open as a page

What is a classloader leak in Java, and what symptom does it typically produce?

level: middleimportance: should knowfreq 45%

basics

~20 s

It happens when something keeps a reference to a class (or its instance/static field) loaded by a custom classloader, so the JVM can never unload that classloader. Its classes pile up in metaspace, eventually causing OutOfMemoryError: Metaspace.

open as a page

Name the JDK's live JVM monitoring and profiling tools and say what each is best at: jstat, VisualVM, Java Flight Recorder, and async-profiler.

level: middleimportance: should knowfreq 50%

basics

~20 s

jstat prints live GC and memory stats from the command line. VisualVM is a GUI that shows memory, threads, and lets you take dumps. Java Flight Recorder records detailed events with very low overhead for later analysis. async-profiler is a low-overhead sampling profiler great for CPU and allocation flame graphs.

open as a page

What is a PhantomReference in Java, and why does its get() method always return null?

level: middleimportance: should knowfreq 35%

basics

~20 s

A PhantomReference is the weakest reference type. Its get() always returns null on purpose, so you can never resurrect the object. It only exists to tell you, via a ReferenceQueue, that the object has already been collected so you can run cleanup.

open as a page

What is a WeakReference in Java, and when is its referent reclaimed by the garbage collector?

level: middleimportance: should knowfreq 55%

basics

~20 s

A WeakReference holds an object without keeping it alive. Once nothing else strongly points to that object, the garbage collector can reclaim it at the next collection, and the weak reference's get() then returns null.

open as a page

What is java.lang.ref.Cleaner, why does it replace finalize(), and how do you use it correctly?

level: seniorimportance: should knowfreq 52%

basics

~20 s

Cleaner runs a cleanup action after an object becomes unreachable, using phantom references and a background thread. It replaces finalize(), which was unreliable and is deprecated. The key rule: the cleanup action must not reference the object it cleans up.

open as a page

How do you diagnose an OutOfMemoryError in production? Distinguish the common OOM kinds and the tools you'd use.

level: seniorimportance: should knowfreq 60%

basics

~20 s

Read the OutOfMemoryError message — it tells you which kind: heap space, Metaspace, GC overhead limit, or unable to create native thread. Capture a heap dump (-XX:+HeapDumpOnOutOfMemoryError), open it in a tool like Eclipse MAT, and find what's holding the most memory.

open as a page

Explain the reachability ladder in java.lang.ref: strong, soft, weak, and phantom references — and when you'd use each.

level: seniorimportance: should knowfreq 64%

basics

~20 s

A normal (strong) reference keeps an object alive. SoftReference lets the GC drop the object only when memory is low (good for caches). WeakReference lets it be collected as soon as nothing strong points to it (good for canonicalizing maps). PhantomReference signals after collection, for cleanup.

open as a page

Why are ThreadLocals on pooled threads a notorious cause of classloader leaks, and how do you avoid it?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Pooled threads (like a server's thread pool) outlive your app. If a request sets a ThreadLocal to an app object and never removes it, that value stays attached to the long-lived thread, keeping your app's classloader alive. Always remove() ThreadLocals in a finally block.

open as a page

Walk through how you would diagnose a slow memory leak in a long-running production Java service, from first symptom to root cause.

level: seniorimportance: should knowfreq 46%

basics

~20 s

Confirm the leak by watching memory climb over time and never fully recover after GC. Enable an automatic heap dump on OutOfMemoryError, or take dumps at intervals and compare. Open the dump in a tool like Eclipse MAT, sort by retained size, find the object retaining the most, and trace its path to GC roots to see what code keeps it alive.

open as a page

A long-running Java service shows steadily climbing heap usage and eventually OOMs. How do you confirm it's a leak and find the cause?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Watch the heap after garbage collection: if the live (post-GC) size keeps trending up over time instead of returning to a baseline, that's a leak, not just busy memory. Then take a heap dump, find the objects with the largest retained size, and trace what GC root is keeping them alive — that points at the offending reference.

open as a page

showing 1–30 of 48