Fundamentals 20 min read

Understanding Java Runtime Memory Areas and the Java Memory Model

This article explains the distinction between Java memory regions and the Java Memory Model, describes each JVM runtime data area—including the program counter, stacks, heap, metaspace, and direct memory—and outlines how the model governs visibility, ordering, and synchronization in concurrent programs.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding Java Runtime Memory Areas and the Java Memory Model

Java memory regions and the Java Memory Model (JMM) are distinct concepts: memory regions refer to how the JVM partitions runtime data, while JMM defines the abstract relationship between threads and main memory, governing visibility and ordering of shared variables.

Java Runtime Data Areas

The JVM automatically manages memory; understanding its layout is essential for diagnosing leaks and out‑of‑memory errors. After JDK 8 the memory layout changed, as shown in the diagrams below.

Prior to JDK 8 the layout included a permanent generation (PermGen). The permanent generation stored class metadata and constant pool entries, and could cause java.lang.OutOfMemoryError: PermGen when overloaded, prompting the move to Metaspace.

PermGen often overflowed, leading developers to seek a more flexible memory area and to unify HotSpot with JRockit, which lacks a permanent generation.

Metaspace replaces PermGen; class metadata moves to native memory, while string constants move to the Java heap.

Program Counter (PC) Register

The PC register is a small memory space that holds the bytecode line number of the currently executing instruction for each thread. It is thread‑private and never throws an OutOfMemoryError.

Java Virtual Machine Stack

The JVM stack is also thread‑private and stores stack frames for each method invocation, containing the local variable table, operand stack, dynamic linking information, and return address.

1. Local Variable Table

The table stores method parameters and local variables. For non‑static methods, index 0 holds the reference to the owning object (4 bytes). The STORE bytecode writes values from the operand stack back to this table.

The stack can throw StackOverflowError if a thread requests a depth beyond the allowed limit, or OutOfMemoryError if it cannot be expanded.

2. Operand Stack

The operand stack starts empty; bytecode instructions push and pop values during method execution. All JVM instructions are defined in terms of stack operations.

3. Dynamic Linking

Each stack frame contains a reference to the method’s entry in the constant pool, enabling dynamic method resolution.

4. Return Address

Methods can exit normally (via RETURN, IRETURN, etc.) or abruptly due to an exception. In either case the return address is used to resume execution in the caller.

Native Method Stack

The native method stack serves the same purpose as the JVM stack but for native (JNI) methods. In HotSpot it is often merged with the JVM stack. It can also throw StackOverflowError or OutOfMemoryError (native heap OOM).

Java Heap

The heap is the largest shared memory area, created at JVM startup, used to allocate object instances. It is managed by garbage collectors and is divided into generations (young and old), with further sub‑areas such as Eden, Survivor spaces, and thread‑local allocation buffers (TLABs).

If the heap cannot satisfy an allocation and cannot be expanded (via -Xmx / -Xms ), the JVM throws OutOfMemoryError .

Method Area

The method area (a non‑heap region) stores loaded class metadata, static variables, and the runtime constant pool. Before JDK 8 it was implemented as PermGen; since JDK 8 it is implemented as Metaspace, which allocates memory from the native heap.

Metaspace eliminates many of the limitations of PermGen, such as fixed size and GC overhead, and aligns HotSpot with JRockit.

Runtime Constant Pool

The runtime constant pool is part of the method area and holds literals and symbolic references after class loading. It can grow dynamically at runtime (e.g., via String.intern() ).

Direct Memory

Direct memory is off‑heap memory allocated via NIO’s ByteBuffer . It is not part of the JVM‑defined memory regions but can improve performance by avoiding copies between Java heap and native memory. It is limited only by the underlying OS memory.

Java Memory Model (JMM)

The JMM defines how threads interact through shared memory (heap). It specifies when writes to shared variables become visible to other threads.

Cache and Consistency

Modern CPUs use caches; each core may have its own cache, leading to potential inconsistencies when multiple cores access the same memory location. Memory‑coherence protocols enforce a consistent view.

Main Memory and Working Memory

All variables reside in main memory; each thread has its own working memory (a local copy). Threads read/write variables only in their working memory, synchronizing with main memory via the JMM rules.

Reordering and Happens‑Before

Compilers and processors may reorder instructions for performance. JMM defines three kinds of reordering (compiler, instruction‑level, and memory‑system) and provides the happens‑before relation to guarantee visibility and ordering. Program order rule: actions in a single thread happen‑before subsequent actions in that thread. Monitor lock rule: unlocking a monitor happens‑before a subsequent lock of the same monitor. Volatile variable rule: a write to a volatile field happens‑before any later read of that field. Transitivity: if A happens‑before B and B happens‑before C, then A happens‑before C.

volatile Keyword

The volatile modifier provides lightweight synchronization: it guarantees visibility of writes to all threads and prevents certain kinds of instruction reordering, but it does not make compound actions atomic. For full atomicity, synchronized or explicit locks are required.

References: "Deep Understanding of the Java Virtual Machine (2nd Edition)", "Java Development Handbook", "Understanding the Java Memory Model".
JavaJVMConcurrencyGarbage CollectionMemory ModelMetaspace
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.