JVM — Cheat Sheet

Tags: java, jvm, garbage-collector, bytecode, memory-management, concurrency, performance

Level: intermediate

TL;DR: Core architecture of the Java Virtual Machine, covering runtime data areas, execution engine, garbage collection mechanisms, and tuning flags.

Key concepts

ClassLoader loads, links (verifies, prepares, resolves), and initializes .class bytecode files dynamically.

JVM memory is split into Heap, JVM Stack, Method Area / Metaspace, PC Register, and Native Method Stack.

Heap stores all object instances and arrays, shared across all executing threads.

Metaspace resides in native memory starting from Java 8, replacing the fixed-size PermGen.

Each thread has its own call stack storing frames with local variables, operand stack, and frame data.

Execution engine interprets bytecode and compiles hotspots to native assembly via JIT compilers (C1 and C2).

Tiered compilation combines fast startup with C1 and high peak optimization with C2.

Stop-The-World (STW) pauses freeze all application threads while GC updates or relocates object references.

Generational hypothesis assumes most created objects die young, motivating Young (Eden, Survivor) and Tenured generations.

Modern collectors like G1, ZGC, and Shenandoah focus on low-latency, region-based concurrent collection.

Typical questions and ready answers

Q: What is the difference between JVM Stack and Heap memory?R: The Stack holds thread-specific execution frames and primitive local variables, cleaned up on method exit. The Heap holds shared object instances and depends on the Garbage Collector for reclamation.

Q: How does JIT compilation optimize bytecode execution at runtime?R: It monitors method invocation counters, compiles frequently called bytecode into native machine code, and applies optimizations like method inlining, loop unrolling, and escape analysis.

Q: How does Metaspace differ from the legacy PermGen?R: PermGen had a fixed contiguous size inside JVM heap limits. Metaspace uses off-heap native memory and expands automatically up to OS limits unless capped with specific flags.

Q: What is escape analysis and how does scalar replacement work?R: The compiler checks if an object reference leaves the allocating method scope. If it never escapes, the JVM can eliminate heap allocation and break the object into primitive local variables on the stack.

Pitfalls and common mistakes

Unintentional object retention via static collections, unclosed streams, or lingering thread locals causes OutOfMemoryError.

Setting excessive heap sizes with traditional collectors drastically increases Stop-The-World pause durations.

Confusing StackOverflowError (exhausted call stack depth) with OutOfMemoryError (exhausted heap or metaspace limit).

Relying on System.gc() in application code, which triggers costly full GC runs instead of letting heuristics govern cycles.

Omitting a maximum cap on Metaspace, allowing rogue dynamic class-generation libraries to exhaust host OS native memory.

Snippets and commands

# Common memory configuration flags
java -Xms4g -Xmx4g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar app.jar

# Select specific garbage collector (G1GC is default since Java 9)
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar
java -XX:+UseZGC -XX:+ZGenerational -jar app.jar

# Diagnostic tools and thread/heap dumps
jcmd <PID> VM.version
jcmd <PID> Thread.print > thread_dump.tdump
jcmd <PID> GC.heap_dump /tmp/heap_dump.hprof

To review

[ ] ZGC colored pointers and load barriers

[ ] G1 GC remembered sets (RSet) and card tables

[ ] Safe points and thread coordination during GC

[x] Generational hypothesis and Eden vs Survivor promotion

[x] JVM memory model: Stack vs Heap allocation boundaries

References

Java Virtual Machine Specification (Oracle SE Editions)

Java Performance: In-Depth Advice for Tuning and Acceleration (Scott Oaks)

Jarvis Interviews
Jarvis