Understanding JVM Runtime Data Areas: From JDK 8 to JDK 17
This article walks through the five JVM runtime data areas, explains the distinction between the JVM specification and HotSpot implementation, compares the PermGen to Metaspace transition from JDK 8 to JDK 17, and provides hands‑on code to reproduce each type of memory‑related OutOfMemoryError.
1. Building a Memory Map
The JVM specification defines five runtime data areas but leaves their concrete implementation to each JVM. HotSpot, the default JVM, implements these areas as follows: program counter, Java virtual stack, native method stack (all thread‑private), and heap plus method area (both shared across threads). Understanding which area is private or shared is the foundation for later topics such as garbage collection and concurrency.
2. Demonstrating the Areas with an Order Example
A simple OrderService program is used to illustrate where each piece of data lives:
public class OrderService {
// static variable: class‑level data
private static int totalCount = 0;
public static void main(String[] args) {
OrderService service = new OrderService();
Order order = service.createOrder(1001L, 99); // ← focus this line
System.out.println(order);
}
public Order createOrder(long userId, int amount) {
Order order = new Order(userId, amount);
totalCount++;
return order;
}
}When createOrder executes, the program counter records the current bytecode, the virtual stack holds two frames (for main and createOrder) with local variables and the this reference, the newly created Order object resides in the heap, and the class metadata and static totalCount live in the method area.
3. Program Counter
The program counter is a tiny thread‑private memory slot that stores the address of the next bytecode instruction. It never throws an OutOfMemoryError because its size is fixed. For native methods the counter is undefined because execution jumps to native code.
4. Java Virtual Stack and Native Method Stack
4.1 Stack Frames
Each method call creates a stack frame containing a local variable table, an operand stack, a dynamic link to the runtime constant pool, and a return address. Slots for primitive types occupy one entry, while long and double occupy two. In instance methods slot 0 always holds this.
4.2 Stack‑Related Exceptions
StackOverflowError: caused by exceeding the maximum stack depth, typically by unbounded recursion. OutOfMemoryError (stack): occurs when the JVM cannot allocate a new stack for a newly created thread; HotSpot’s stack size is fixed by -Xss, so this error is usually seen as “unable to create new native thread”.
Tip: the default -Xss on 64‑bit systems is roughly 512 KB–1 MB. Reducing it (e.g., -Xss256k ) makes StackOverflowError appear faster for experiments.
5. Heap
The heap is the largest shared memory region, storing all object instances and arrays. It is the primary target of garbage collection. HotSpot logically divides the heap into Young and Old generations (Eden, Survivor spaces), but the article only notes that such a division exists.
Heap size is controlled by -Xms (initial) and -Xmx (maximum). A common practice is to set them to the same value to avoid costly resizing during runtime.
When the heap cannot accommodate new objects, the JVM throws java.lang.OutOfMemoryError: Java heap space. Detailed analysis of such OOMs is deferred to a later article.
6. Method Area (PermGen → Metaspace)
The method area stores class metadata, the runtime constant pool, and static variables. In JDK 7 and earlier HotSpot used the heap‑resident PermGen; starting with JDK 8 it switched to Metaspace, which allocates native memory instead of heap memory.
Key differences:
Metaspace size is limited only by physical memory unless -XX:MaxMetaspaceSize is set.
PermGen required explicit size parameters ( -XX:PermSize, -XX:MaxPermSize) and frequently caused OOMs.
Typical JVM flags:
# JDK 7 and earlier (PermGen)
-XX:PermSize=128m -XX:MaxPermSize=256m
# JDK 8 and later (Metaspace)
-XX:MetaspaceSize=128m # initial high‑water mark for class‑unload GC
-XX:MaxMetaspaceSize=256m # optional upper bound; default is unlimitedBecause Metaspace can grow until native memory is exhausted, production environments often set a reasonable -XX:MaxMetaspaceSize to surface a OutOfMemoryError: Metaspace before the whole machine runs out of RAM.
6.3 String Constant Pool Migration
Since JDK 7 the string constant pool has been moved from PermGen to the heap, allowing it to benefit from regular garbage collection.
7. Direct Memory
Direct memory (allocated via NIO’s DirectByteBuffer) is not part of the JVM spec but is used by HotSpot. It is controlled by -XX:MaxDirectMemorySize (default equals -Xmx) and can cause java.lang.OutOfMemoryError: Direct buffer memory. Unlike heap OOMs, the Java heap may appear healthy while the process runs out of native memory.
8. Hands‑On Reproducing Each OOM
Three code snippets are provided to trigger the most common OOMs:
Heap OOM – run with -Xms16m -Xmx16m -XX:+HeapDumpOnOutOfMemoryError and continuously allocate 1 MB byte arrays in a live list.
Stack OOM – run with -Xss256k and invoke an infinite recursive method to exceed the stack depth.
Metaspace OOM – run with -XX:MaxMetaspaceSize=32m and repeatedly generate new classes using CGLIB/ASM (cache disabled) to fill Metaspace.
Running the same Metaspace code on JDK 7 with -XX:MaxPermSize=32m produces a java.lang.OutOfMemoryError: PermGen space, illustrating the historical change.
Conclusion
The five runtime data areas are split by a clear private/shared boundary: program counter, virtual stack, and native stack are thread‑private; heap and method area are shared.
Objects live in the heap, references in the stack, and class templates in the method area.
The program counter is the only area that cannot cause OOM.
JDK 8 replaced PermGen with Metaspace, moving the method‑area storage to native memory and eliminating the MaxPermSize limit.
Direct memory, although outside the spec, is a common source of hidden OOMs.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
