JVM Interview Questions
JVM internals are a staple of senior Java interviews. These questions cover memory areas, garbage collection, class loading, and performance.
Memory Areas
Q: Describe JVM memory structure.
┌─────────────────────────────────────────┐
│ Thread-shared: │
│ Heap (objects) │
│ Metaspace (class metadata) │
│ Code Cache (JIT compiled code) │
│ Thread-private: │
│ Program Counter Register │
│ JVM Stack (frames, local vars) │
│ Native Method Stack │
└─────────────────────────────────────────┘
Q: Stack vs Heap?
| Stack | Heap | |
|---|---|---|
| Stores | Method frames, local variables, references | Objects, arrays |
| Size | Fixed per thread (~1MB default) | Configurable (-Xmx) |
| GC | No | Yes |
| Thread | Per-thread | Shared |
| Overflow | StackOverflowError | OutOfMemoryError |
void method() {
int x = 10; // stack (primitive)
Person p = new Person(); // reference on stack, object on heap
}
Garbage Collection
Q: Which objects are eligible for GC?
Objects not reachable from GC roots:
- Static variables
- Active thread stacks
- JNI references
- Syncmonitors
Q: Describe GC roots and reachability.
GC Root → Object A → Object B → Object C
↘ Object D
If reference from A to D is removed, D becomes eligible for GC
(even if B still exists and B originally created D)
Q: G1 vs CMS vs ZGC?
| CMS (deprecated) | G1 (default) | ZGC | |
|---|---|---|---|
| Pause type | Concurrent mark, STW compact | Incremental regions | Nearly all concurrent |
| Fragmentation | Yes (no compact) | Compacts regions | Compacts |
| Heap size | Medium | Medium–large | Large (8g+) |
| Pause target | Unpredictable | Configurable (200ms) | Sub-ms |
| Status | Removed in Java 14 | Default since Java 9 | Production since Java 15 |
Q: What triggers a Full GC?
- Old generation fills up
- Metaspace exhaustion
- System.gc() called (usually ignored in production)
- Allocation failure after minor GC
- Heap dump request
Class Loading
Q: Class loading process?
Loading → Linking (verify, prepare, resolve) → Initialization
- Loading — find bytecode, create Class object
- Verify — bytecode validity
- Prepare — allocate static variable memory, set defaults
- Resolve — symbolic references → direct references (optional)
- Initialize — execute static blocks, assign static fields
Q: Parent delegation model?
Bootstrap ClassLoader (rt.jar)
↑
Extension ClassLoader (ext/)
↑
Application ClassLoader (classpath)
↑
Custom ClassLoader
A classloader asks its parent first. Only loads if parent cannot find the class. Prevents core class tampering.
Q: How to break parent delegation?
Custom classloader overrides loadClass():
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("com.mycompany.plugin.")) {
return findClass(name); // load locally, skip parent
}
return super.loadClass(name, resolve);
}
Used in: OSGi, Tomcat (web app isolation), plugin architectures.
JIT Compilation
Q: How does JIT work?
Bytecode → Interpreter (slow) → Hot methods detected → JIT compile to native code → Execute native
Tiered compilation (Java 7+):
- Interpret
- C1 (client) compiler — fast compile, moderate optimization
- C2 (server) compiler — slow compile, aggressive optimization
Hot methods identified by invocation counters.
Common Scenario Questions
Q: OutOfMemoryError in production — how to diagnose?
- Check error type (heap, metaspace, direct memory, threads)
- Analyze heap dump with Eclipse MAT
- Look for leak suspects, dominator tree
- Check GC logs for frequent Full GC
- Review recent code changes (new caches, unclosed resources)
Q: How would you reduce GC pause times?
- Switch to ZGC or G1 with lower
MaxGCPauseMillis - Reduce object allocation rate
- Increase heap size if old gen is consistently full
- Fix memory leaks causing premature Full GC
- Use object pooling for frequently allocated objects