Runtime data areas and class loading
advanced16 min readLesson 125 of 180
Heap vs stacks vs metaspace, and the exact triggers of lazy class initialization.
The JVM spec (ยง2.5, ยง5) divides runtime memory into areas with different lifetimes and failure modes. The ones that matter daily:
- Heap: all objects; shared by all threads; GC-managed.
OutOfMemoryErrorhere means your live set does not fit. - Per-thread stacks: one frame per invoked method (locals + operand
stack).
StackOverflowErrormeans depth, not heap size. - Metaspace: class metadata (native memory).
OutOfMemoryError: Metaspaceusually means classes are being generated at runtime and never unloaded. - PC register per thread โ why threads can be suspended anywhere.
Class initialization (JLS ยง12.4) is lazy and triggerable. Two ways to name a class behave differently:
Class<?> a = Loaded.class; // NO static init
Class<?> b = Class.forName("Loaded"); // static init runs
A class literal is a compile-time constant reference โ it does not use the
class. forName initializes it. So does new, static method calls, and
accessing a non-constant static field. This laziness is why a broken static
initializer can hide for weeks until the first real use throws
ExceptionInInitializerError.