| Heap | Object instances; Young Gen (Eden+S0+S1) + Old Gen; GC managed |
| Metaspace | Class metadata; off-heap (native memory); replaces PermGen (Java 8) |
| Stack | Per-thread frames (local vars, operand stack, method calls) |
| PC Register | Per-thread: address of current bytecode instruction |
| Native Method Stack | For native (JNI) method invocations |
| Code Cache | JIT-compiled native code; off-heap |
JVM Architecture & Class Loading
Q1. What are the main components of the JVM?
A: 1) Class Loader Subsystem: loads, links, and initializes class files. 2) Runtime Data Areas: Heap, Metaspace, Stack (per-thread), PC Register, Native Stack, Code Cache. 3) Execution Engine: Interpreter (bytecode), JIT Compiler (C1 client/C2 server), GC. 4) Native Method Interface (JNI): bridge to native code. 5) Native Method Libraries: platform-native code.
Q2. What is the class loading process?
A: Three phases: 1) Loading: read .class file into memory, create Class object. 2) Linking: Verification (bytecode validity), Preparation (allocate static fields with default values), Resolution (symbolic references → direct references). 3) Initialization: execute static initializers and static field assignments. Classes loaded lazily — only when first used.
Q3. What are the class loaders and the delegation model?
A: Hierarchy: Bootstrap ClassLoader (JVM built-in, loads rt.jar/java.*) → Platform ClassLoader (Java 9+, extension modules) → Application ClassLoader (classpath). Delegation: when a class loader is asked to load a class, it first delegates to parent. Only loads itself if parent can't find it. Prevents classes from being loaded twice and maintains trusted bootstrap classes.
Q4. What is the parent delegation model exception?
A: SPI (Service Provider Interface) pattern breaks parent delegation: java.sql.DriverManager (bootstrap loaded) needs to load user's JDBC driver (application classpath). Context ClassLoader solves this: Thread.currentThread().getContextClassLoader() allows bootstrap-loaded classes to load application classes. OSGi also breaks parent delegation for module isolation.
Q5. What is Class.forName() vs ClassLoader.loadClass()?
A: Class.forName(name): loads AND initializes the class (runs static initializers). Class.forName(name, initialize, loader): with initialize=false, loads but doesn't initialize. ClassLoader.loadClass(name): loads but does NOT initialize. JDBC used Class.forName("com.mysql.Driver") to trigger static initializer that registers the driver. Java 9+ JDBC loads via SPI — Class.forName not needed.
Q6. What is class unloading?
A: Classes can be unloaded when their ClassLoader is GCed (and no other strong references to the class exist). Bootstrap-loaded classes are never unloaded. Application ClassLoader lives for JVM lifetime. Dynamic class loaders (web containers, OSGi) can create isolated class loaders that are GCed — enabling hot deployment. PermGen (pre-Java 8) OOM was often caused by class loader leaks preventing unloading.
Q7. What replaced PermGen in Java 8?
A: Metaspace replaced PermGen. Key differences: Metaspace uses native memory (not JVM heap) — grows dynamically up to OS limit or -XX:MaxMetaspaceSize. PermGen was fixed-size heap region (-XX:MaxPermSize) — a common OOM source. Metaspace stores class metadata, method bytecode, interned strings (moved to heap Java 7+). Still possible to OOM Metaspace with class loader leaks.
Q8. What is the JVM stack frame structure?
A: Each method call creates a stack frame containing: 1) Local variable array (index 0 = this for instance methods, then params, then locals). 2) Operand stack (work area for bytecode operations). 3) Constant pool reference (for symbolic resolution). 4) Return address. Stack depth = number of nested method calls. StackOverflowError = stack limit exceeded (recursive calls).
Q9. What is the bytecode instruction set?
A: JVM bytecode: stack-based instruction set in .class files. Categories: load/store (iload, istore, aload, astore), arithmetic (iadd, imul, isub), type conversion (i2l, l2i), object operations (new, getfield, putfield), method invocations (invokevirtual, invokespecial, invokestatic, invokeinterface, invokedynamic), control flow (if*, goto, tableswitch), stack manipulation (dup, pop, swap).
Q10. What is invokedynamic and how does it relate to lambdas?
A: invokedynamic (Java 7): defers method binding to runtime via a bootstrap method. Java lambdas and method references compile to invokedynamic — the JVM uses LambdaMetafactory as bootstrap to create functional interface implementations at runtime. This is more efficient than anonymous inner classes (no .class file per lambda, JVM can optimize). Dynamic languages (Groovy, JRuby) also use invokedynamic.
JVM Memory & Garbage Collection
Q11. What is the heap structure in Java?
A: Heap: Young Generation (Eden + Survivor0 + Survivor1) + Old Generation (Tenured). Default: Young = 1/3 heap, Old = 2/3. Eden: where new objects are allocated. Survivors: objects surviving minor GC move here. After N GC cycles (tenuring threshold), objects promoted to Old Gen. Old Gen: long-lived objects; collected in major/full GC.
New Objects
Long-lived Objects
Q12. What is minor GC vs major GC vs full GC?
A: Minor GC: collects Young Generation. Triggered when Eden is full. Fast (milliseconds). Stop-the-world pause but short. Major GC: collects Old Generation. Triggered when Old Gen fills. Slower (seconds). Full GC: collects both Young + Old + Metaspace + Code Cache. Usually triggered by System.gc() or OOM risk. Most GC tuning aims to minimize Full GC frequency.
Q13. What is the generational hypothesis?
A: Most objects die young (short-lived temporaries, request-scoped objects). A few objects survive long (caches, connections, configuration). Generational GC exploits this: collect Young frequently (most garbage here), collect Old rarely (few long-lived survivors). This makes GC efficient — spending effort where most garbage is found.
Q14. What are GC roots?
A: GC roots are starting points for reachability analysis. An object is alive if reachable from any GC root. GC roots include: local variables in all thread stacks, static fields, JNI references, class objects, synchronization monitors. Unreachable objects are garbage. GC marks from roots (mark phase) then collects unmarked objects (sweep/compact phase).
Q15. What is stop-the-world (STW) pause?
A: STW: JVM pauses all application threads during certain GC phases. Required for: accurate root scanning (threads must be stopped so their stack frames don't change), object relocation (can't move object while application uses it). Modern GCs (G1, ZGC, Shenandoah) minimize STW by doing most work concurrently with application threads. STW pauses directly impact latency.
Q16. What GC algorithms does Java support?
A: Serial GC: single-threaded; use for small heaps, client apps. Parallel GC: multi-threaded STW GC; high throughput, higher pauses; default Java 8. G1 GC: region-based; balanced throughput and latency; default Java 9+. ZGC: concurrent, sub-millisecond pauses; Java 11 (production Java 15). Shenandoah: concurrent, low pause; OpenJDK 12. Epsilon GC: no-op; for benchmarking/testing.
Q17. How does Parallel GC work?
A: Parallel (Throughput) GC: uses multiple threads for GC (STW). Young Gen: parallel copying (Eden → Survivors/Old). Old Gen: parallel mark-sweep-compact. Goal: maximize throughput (minimize total GC time as fraction of runtime). Accepts longer individual pauses. Good for: batch jobs, analytics, scientific computing. Not good for: interactive apps with latency requirements.
Q18. How does G1 GC work?
A: G1 (Garbage First, Java 9 default): divides heap into equal-sized regions (~2048 regions, 1-32MB each). No fixed Young/Old boundary — regions are labeled Young or Old dynamically. Concurrent marking runs alongside application. Evacuation: copies live objects from "garbage-first" (most-garbage) regions. Predictable pause targets: -XX:MaxGCPauseMillis=200 (default). Old Gen also collected incrementally.
Q19. What is ZGC?
A: ZGC (Java 11+, production Java 15): concurrent, low-latency GC with sub-millisecond pauses (99.9th percentile). Key innovations: colored pointers (metadata in pointer bits), load barriers (update references on object access), concurrent relocation (moves objects while app runs). Pauses: initial mark, remark, relocate start — all very short. Java 21: Generational ZGC for better throughput. Scales to multi-terabyte heaps.
Q20. What is Shenandoah GC?
A: Shenandoah (OpenJDK 12+): concurrent, low-pause GC. Concurrent evacuation: moves objects while application runs — uses read barriers (forward pointer) to redirect loads. Similar goals to ZGC but different implementation. Does NOT have generational mode (as of OpenJDK 21). Available in OpenJDK, not Oracle JDK. Good for latency-sensitive applications on OpenJDK.
Q21. What is the difference between throughput and latency in GC?
A: Throughput: fraction of time application runs vs GC runs. Parallel GC maximizes throughput (minimal total GC time). Latency: individual GC pause duration. ZGC/Shenandoah minimize individual pauses. Trade-off: reducing pauses usually means more total GC work (higher overhead). G1 balances both. Choose based on your SLA: batch jobs → throughput; interactive → latency.
Q22. What are key JVM GC flags?
-Xms2g -Xmx4g # min/max heap size
-XX:+UseG1GC # G1 GC (default Java 9+)
-XX:+UseZGC # ZGC (Java 11+)
-XX:MaxGCPauseMillis=200 # G1 pause target
-XX:NewRatio=2 # Old/Young ratio (2 = old is 2x young)
-XX:SurvivorRatio=8 # Eden/(Survivor*2) ratio
-XX:MaxMetaspaceSize=256m # limit Metaspace
-XX:+PrintGCDetails # log GC details (deprecated → use -Xlog:gc*)
-Xlog:gc*:file=gc.log # structured GC logging (Java 9+)
-XX:+HeapDumpOnOutOfMemoryError # dump heap on OOM
Q23. What is the tenuring threshold?
A: Tenuring threshold: how many minor GC cycles an object must survive in Survivor space before being promoted to Old Gen. Default: 15 (max). JVM may lower adaptively (-XX:+UseAdaptiveSizePolicy). Objects larger than -XX:PretenureSizeThreshold are allocated directly in Old Gen. Setting too low → premature promotion (Old Gen fills); too high → Survivors fill → premature promotion anyway.
Q24. What is the TLAB (Thread-Local Allocation Buffer)?
A: TLAB: each thread gets a private buffer in Eden for object allocation. Eliminates contention on Eden pointer — threads allocate from their own buffer without synchronization (just bump pointer). When TLAB fills, thread gets a new one. Small objects use TLAB; large objects allocated outside TLAB (rare). Default behavior — almost all object allocations are lock-free bump-pointer.
Q25. What is escape analysis?
A: Escape analysis: JIT detects if an object "escapes" the current method — if not, it's heap-allocated but may be optimized. Optimizations: stack allocation (object lives on stack, GC-free), lock elision (synchronized on non-escaping object removed), scalar replacement (object fields put in registers). Enables allocating small, short-lived objects with zero heap/GC cost.
Q26. What is the JIT compiler (Just-In-Time)?
A: JIT compiles frequently-executed bytecode to native machine code. Java starts interpreted (slow), profiles execution, then JIT-compiles "hot" methods. HotSpot JIT: C1 (client/fast compile, basic optimizations) and C2 (server/slow compile, aggressive optimizations). Tiered compilation (Java 7+): interpreted → C1 → C2 as method gets hotter. JIT can de-optimize and re-optimize as profiles change.
Q27. What is AOT (Ahead-Of-Time) compilation?
A: AOT compiles Java to native before runtime (not at runtime like JIT). GraalVM Native Image: compiles Spring Boot app to native executable. Benefits: instant startup (no JIT warmup), lower memory (no JIT overhead). Drawbacks: longer build time, no JIT adaptive optimizations, limited reflection/dynamic class loading. Spring Boot 3 supports GraalVM native image officially.
Q28. What is GraalVM and what does it provide?
A: GraalVM: JVM + compiler + runtimes. Key features: 1) High-performance JIT (replaces C2 for some workloads). 2) Native Image: AOT compilation to standalone executable. 3) Polyglot API: run JavaScript/Python/Ruby inside Java. 4) LLVM bitcode support. HotSpot now includes Graal JIT (-XX:+UseJVMCICompiler). Spring Boot 3 + GraalVM Native Image is the leading Java cloud-native approach.
Q29. What are common causes of OutOfMemoryError?
A: "Java heap space": heap exhausted (too many live objects, memory leaks). "Metaspace": class loader leak (dynamic class loading without unloading). "GC overhead limit exceeded": JVM spending >98% time GCing with <2% reclaim. "Direct buffer memory": NIO ByteBuffer.allocateDirect() exceeds -XX:MaxDirectMemorySize. "Unable to create native thread": OS thread limit. "PermGen" (Java 7-): class metadata overflow (replaced by Metaspace in Java 8).
Q30. What is a memory leak in Java?
A: Java memory leak: objects that are no longer needed but still reachable from GC roots — GC can't collect them. Common causes: 1) Static collections holding references. 2) Listeners/callbacks not removed. 3) ThreadLocal not removed in thread pools. 4) Inner class holding outer class reference. 5) Caches without expiration (use WeakReference/SoftReference or Caffeine). 6) Class loader leaks in web servers.
Q31. How do you detect memory leaks?
A: Tools: 1) Heap dump + Eclipse MAT or VisualVM: take heap dump (-XX:+HeapDumpOnOutOfMemoryError), load in MAT, find retained heap, look for large objects/dominator tree. 2) jmap -histo <pid>: histogram of object counts by class. 3) Java Flight Recorder (JFR): continuous memory profiling. 4) YourKit/JProfiler: commercial profilers. Pattern: repeated heap dumps show growing objects that should have been collected.
Q32. What is the difference between heap dump and thread dump?
A: Heap dump: snapshot of all objects in heap memory — used for diagnosing OOM, memory leaks, object retention analysis. Generated with: jmap -dump:live,format=b,file=heap.hprof <pid> or -XX:+HeapDumpOnOutOfMemoryError. Thread dump: snapshot of all thread states and stack traces — used for diagnosing deadlocks, hung threads, high CPU. Generated with: jstack <pid> or kill -3 <pid>.
Q33. What is the G1 GC Humongous allocation?
A: G1 considers objects > half a region size "humongous". Humongous objects are allocated directly in Old Gen (contiguous regions), not Eden. They're GCed in marking cycle, not minor GC. Frequent humongous allocations bypass Young GC efficiency. Common cause: large arrays, big String/byte[]. Tune with -XX:G1HeapRegionSize (larger = less humongous promotion).
Q34. What is card table in GC?
A: Card table: data structure to track cross-generational references (Old Gen object pointing to Young Gen object). Divided into 512-byte cards. When an Old Gen object is modified, its card is marked "dirty". Minor GC scans only dirty cards instead of entire Old Gen, making minor GC fast. Write barriers maintain the card table. Cards also used by G1 for remembered sets.
Q35. What is the remembered set in G1 GC?
A: In G1, each region has a Remembered Set (RSet) tracking references FROM other regions INTO this region. During collection, RSet allows finding all pointers to the collected region without scanning entire heap. Smaller RSets = faster GC. Large RSets indicate many inter-region references — fragmented data structures. RSet overhead: ~5-20% heap overhead for G1.
Q36. What is concurrent GC marking?
A: Concurrent marking: GC marks live objects while application threads run (no STW). Challenge: application modifies object graph during marking — missed objects or incorrectly-marked-dead live objects. Solutions: write/read barriers track modifications (SATB — Snapshot at the Beginning for G1; ZGC/Shenandoah use load barriers). Short STW pauses needed at start (initial mark) and end (remark) to handle modifications.
Q37. What is SATB (Snapshot-At-The-Beginning)?
A: SATB: G1's concurrent marking algorithm. Takes a logical snapshot at marking start — marks objects that were live at that point. Write barriers record reference overwrites during marking to ensure no live objects are missed. More conservative than other approaches — may retain some floating garbage (collected next cycle). ZGC/Shenandoah use different load barrier approach.
Q38. What is GC tuning approach?
A: Step 1: Set -Xms = -Xmx (avoid heap resize). Step 2: Choose GC (-XX:+UseG1GC for latency, Parallel for throughput, ZGC for ultra-low latency). Step 3: Enable GC logging (-Xlog:gc*). Step 4: Analyze logs with GCEasy or GCViewer. Step 5: Tune only if problematic — avoid premature tuning. Step 6: Address application-level issues (reduce object churn, fix leaks) before tuning GC parameters.
Q39. What is the effect of -Xms != -Xmx?
A: If Xms < Xmx: JVM starts with Xms, grows heap as needed (triggers heap expansion + GC). Expansion causes extra GC pauses. In production: set Xms = Xmx to pre-allocate the full heap — no expansion pauses, more predictable performance. Prevents OOM from heap not growing fast enough under sudden load spikes.
Q40. What is String interning and the String pool?
A: String pool: cache of String literals in Java heap (moved from PermGen to heap in Java 7). "hello" == "hello" is true (same pool entry). String.intern() adds a String to pool (returns pool reference). Use intern() to save memory for frequently repeated strings. Risk: too many interned strings can bloat heap. Java 21: String pool uses ConcurrentHashMap internally — efficient lookups.
String a = "hello"; // pool entry
String b = "hello"; // same pool entry
System.out.println(a == b); // true
String c = new String("hello"); // new heap object
System.out.println(a == c); // false
String d = c.intern(); // returns pool entry
System.out.println(a == d); // true
Q41. What is the JVM startup vs throughput trade-off?
A: JVM needs warmup: class loading, JIT compilation, profile collection. Cold startup is slow; peak throughput achieved after warmup (seconds to minutes). Strategies: 1) Keep services warm (don't restart frequently). 2) Lazy initialization (defer non-critical startup work). 3) GraalVM Native Image for instant startup (sacrifices JIT optimizations). 4) AOT compilation with CDS (Class Data Sharing) to reduce loading time.
Q42. What is Class Data Sharing (CDS)?
A: CDS: JVM can dump loaded class metadata to a shared archive file. On next startup, JVM maps the archive into memory (shared across processes) — faster class loading, lower startup time, lower memory per-JVM instance. Application CDS (AppCDS, Java 10+) extends to application classes. Spring Boot supports CDS via spring-boot:process-aot + JVM -XX:SharedArchiveFile. Reduces startup time 20-40%.
Q43. What is the difference between a soft, weak, and phantom reference GC behavior?
| Reference Type | When Collected | Use Case |
|---|---|---|
| Strong | Never (while reachable) | Normal usage |
| Soft | Before OOM (low memory) | Memory-sensitive caches |
| Weak | Next GC cycle | Canonicalization, WeakHashMap |
| Phantom | After finalization | Post-GC cleanup without finalize() |
Q44. What is finalize() and why is it deprecated?
A: finalize(): GC calls this method before collecting an object — for cleanup. Problems: 1) Non-deterministic timing (GC may never run). 2) Can resurrect objects. 3) Finalizer thread can lag — FinalizerQueue backlog causes OOM. 4) Breaks encapsulation. Java 9: deprecated. Java 18: finalize() deprecated for removal. Use: try-with-resources (AutoCloseable), Cleaner API (Java 9), PhantomReference + ReferenceQueue instead.
Q45. What is the Cleaner API (Java 9)?
A: java.lang.ref.Cleaner: modern replacement for finalize(). Register a Cleanable with an action (Runnable) — action runs when object becomes phantom reachable. No "this" in the action (prevents resurrection). Actions run on cleaner thread (or explicitly via clean()). More predictable than finalize(). Used in NIO buffers, JDK internal cleanup.
class Resource implements AutoCloseable {
private static final Cleaner CLEANER = Cleaner.create();
private final Cleaner.Cleanable cleanable;
Resource() {
cleanable = CLEANER.register(this, () -> releaseNativeResource());
}
public void close() { cleanable.clean(); } // explicit cleanup
}
Q46. What is the impact of object allocation rate on GC?
A: High allocation rate = frequent minor GCs. Minor GC is fast but still pauses. Very high rates (GB/second) can overwhelm GC — objects survive to Old Gen not because they're long-lived but because GC can't collect fast enough. Reduce allocation: object pooling (StringBuilder reuse), avoid unnecessary boxing/unboxing, use primitives over wrappers, avoid creating many short-lived objects in hot loops.
Q47. What is GC log analysis?
# Enable GC logging (Java 9+):
-Xlog:gc*:file=/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=50m
# Key metrics to look for in GC log:
# - Pause duration (GC pause time)
# - Heap before/after each collection
# - Allocation rate (how fast heap fills)
# - Promotion failure (OOM risk)
# - Full GC frequency (should be rare)
# Tools: GCEasy.io, GCViewer, Java Mission Control (JMC)
Q48. What is JFR (Java Flight Recorder)?
A: JFR: low-overhead continuous profiling built into JDK (free since Java 11). Records: GC events, thread states, memory allocation, JIT compilations, I/O, class loading. Overhead: <1% CPU. Start recording: -XX:StartFlightRecording=duration=60s,filename=recording.jfr or via JConsole/jcmd. Analyze with Java Mission Control (JMC). Essential for production profiling without restarting JVM.
Q49. What is the difference between CMS and G1 GC?
A: CMS (Concurrent Mark Sweep, removed Java 14): concurrent Old Gen collection, low pause. Problems: fragmentation (no compaction), promotion failures, high CPU for concurrent marking, complex tuning. G1 replaced CMS: region-based, concurrent marking + evacuation (compacts as it collects), predictable pause target, simpler tuning. CMS was default before G1; G1 is default Java 9+.
Q50. What is promotion failure in GC?
A: Promotion failure: during minor GC, a Survivor space object or newly-tenured object can't be copied to Old Gen because Old Gen is full. Forces a Full GC (stop the world, collect everything). Symptoms in GC log: "Promotion failed", "Full GC (Ergonomics)". Fix: increase Old Gen size (adjust -XX:NewRatio), reduce object promotion rate, fix memory leaks.
Q51. What is concurrent mode failure in CMS/G1?
A: G1 concurrent mode failure: GC cannot complete concurrent marking/evacuation before Old Gen fills — falls back to Full GC (single-threaded, very long pause). Triggered by: high allocation rate overwhelming concurrent marking, evacuation failure (no free regions). Fix: increase -XX:G1ReservePercent, increase heap size, tune -XX:MaxGCPauseMillis (makes GC more aggressive), reduce allocation rate.
Q52. What is Generational ZGC (Java 21)?
A: Java 21 introduced Generational ZGC (-XX:+UseZGC -XX:+ZGenerational). Adds Young/Old generation to ZGC — collects short-lived objects (Young Gen) more frequently, Old Gen less frequently. Better throughput than base ZGC (which treated all objects equally). Sub-millisecond pauses maintained. Preferred over base ZGC for most production workloads in Java 21+. Enable with -XX:+UseZGC (Java 21 default uses generational mode).
Q53. What is the direct buffer (off-heap) memory?
A: ByteBuffer.allocateDirect(): allocates off-heap (native) memory. Not managed by GC (no GC overhead for reads/writes). Used for: NIO file/network I/O (no copy between JVM heap and OS buffers), memory-mapped files. GCed when ByteBuffer object is collected (via Cleaner). Limit with -XX:MaxDirectMemorySize. OOM "Direct buffer memory" = off-heap limit reached.
Q54. What is JVM tuning for Spring Boot microservices?
# Typical Spring Boot container JVM flags (Java 21):
JAVA_OPTS="-XX:+UseZGC \
-Xms512m -Xmx512m \
-XX:MaxMetaspaceSize=128m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp/heap.hprof \
-Xlog:gc*:file=/logs/gc.log:time,level:filecount=3,filesize=10m \
-XX:+UseContainerSupport" # important in Docker/K8s
Q55. What is UseContainerSupport?
A: -XX:+UseContainerSupport (default Java 10+): makes JVM aware of Docker container CPU and memory limits. Without it, JVM uses host machine resources (e.g., detects 64GB host RAM, creates large thread pools). With it, JVM respects container limits (e.g., 512MB container → JVM uses 512MB). Critical for Kubernetes/Docker deployments to avoid OOM kills.
Q56. What is the difference between Serial, Parallel, G1, and ZGC from interview perspective?
| GC | Pause | Throughput | Use Case |
|---|---|---|---|
| Serial | High | Low | Small heaps, single-core |
| Parallel | High | High | Batch, analytics |
| G1 | Medium | Good | Default; most apps |
| ZGC | <1ms | Good | Latency-critical, large heaps |
Q57. What are the JVM flags for memory troubleshooting?
-verbose:gc # basic GC output
-XX:+PrintGCDetails # detailed GC (deprecated Java 9)
-Xlog:gc* # all GC events (Java 9+)
-XX:+HeapDumpOnOutOfMemoryError # dump on OOM
-XX:HeapDumpPath=/tmp/ # dump location
-XX:+PrintClassHistogram # class histogram on SIGQUIT
-XX:NativeMemoryTracking=detail # track all JVM memory areas
# Print NMT: jcmd <pid> VM.native_memory detail
Q58. What is Native Memory Tracking (NMT)?
A: NMT: JVM feature to track all JVM native memory usage. Enable with -XX:NativeMemoryTracking=summary|detail. Query with jcmd <pid> VM.native_memory. Shows: heap, metaspace, code cache, thread stacks, GC overhead, internal JVM memory. Use to diagnose: "process memory larger than -Xmx" (common: NMT explains the extra). Total process RSS = heap + metaspace + code cache + thread stacks + off-heap buffers.
Q59. What is the relationship between -Xmx and actual process memory?
A: -Xmx sets HEAP limit. Total process memory > Xmx because: Metaspace (class data), Code Cache (JIT output, default 240MB), Thread stacks (n_threads * 512KB-1MB), Direct buffers (off-heap NIO), GC bookkeeping structures, JVM overhead. Rule: container memory limit = Xmx + 256MB (Metaspace) + 256MB (Code Cache) + thread stack + off-heap buffers. -XX:MaxRAMPercentage=75 in containers sets heap to 75% of container RAM automatically.
Q60. What are JVM diagnostic tools?
A: jstack <pid>: thread dump. jmap -heap: heap info; jmap -dump: heap dump. jcmd: multi-purpose (thread dump, heap dump, JFR, NMT). jstat -gcutil <pid>: GC statistics live. jps: list JVM processes. jinfo: JVM flags and system properties. jconsole, jvisualvm: GUI monitoring. Java Mission Control (JMC): flight recorder analysis. GraalVM VisualVM: enhanced profiler.
Q61. What is the effect of -server vs -client JVM flag?
A: -server: uses C2 JIT (aggressive optimizations, longer warmup, better peak performance). -client: uses C1 JIT (fast startup, lower peak). In modern JDK (Java 8+), tiered compilation is default — C1 then C2, so distinction is less relevant. 64-bit JVM always uses server mode. -server flag is now effectively a no-op on modern JDKs.
Q62. What is JVM ergonomics?
A: JVM ergonomics: automatic selection of default settings based on hardware. JVM detects: CPU count (sets GC thread count), available RAM (sets heap size), environment (client/server). Defaults: -XX:+UseG1GC, heap = 1/4 physical RAM (max 25GB). With UseContainerSupport: respects container limits. Ergonomics makes JVM usable without extensive tuning on modern hardware.
Q63. What is the code cache and what happens when it fills?
A: Code cache: off-heap memory for JIT-compiled native code. Default: 240MB (-XX:ReservedCodeCacheSize). When full: JVM disables JIT (deoptimizes to interpreter) — catastrophic performance drop. Symptoms: "CodeCache is full. Compiler has been disabled." Fix: increase -XX:ReservedCodeCacheSize=512m or more. Profiling with -XX:+PrintCodeCache shows usage. Rare in practice but important to know.
Q64. What is tiered compilation?
A: Tiered compilation (default Java 7+, always on Java 8+): 5 compilation tiers. Tier 0: interpreter. Tier 1: C1 simple (no profiling). Tier 2: C1 + limited profiling. Tier 3: C1 + full profiling. Tier 4: C2 (fully optimized using C1's profile data). JVM moves methods through tiers based on invocation count and back-edge count. Fast startup (interpreter/C1) + peak performance (C2).
Q65. What is the Safepoint in JVM?
A: Safepoint: a point in execution where JVM can pause threads for GC, deoptimization, or other JVM operations. Threads check for safepoint requests at: method returns, back-edges of loops (every N iterations), JNI exits. All threads must reach a safepoint before STW operations begin. Long safepoint latency (threads slow to reach safepoint) = long GC pause not counting actual GC work. Enable safepoint logging: -XX:+PrintSafepointStatistics (Java 8), -Xlog:safepoint (Java 9+).
Post a Comment
Add