What are the main runtime memory areas the JVM divides memory into, and which are shared across threads versus per-thread?
answer
- Heap = shared, objects; Stack = per-thread, frames
- Metaspace = class metadata, native memory, replaced PermGen in Java 8
- PC register + native stack also per-thread
- OOM: heap space vs Metaspace; StackOverflow vs OutOfMemory
basics
~20 sThe 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 sThe 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
Can name heap (objects), stack (method calls/locals), and that the heap is where GC works; knows objects go on the heap.
Explains the shared-vs-per-thread split, what a stack frame holds, and distinguishes StackOverflowError from OutOfMemoryError with their causes.
Adds Metaspace vs PermGen history, generational heap layout, PC register and native stack, and ties the split to why local data needs no synchronization.
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)