Introduction
Java JVM hangs due to deadlocks in application code or internal JVM synchronization. This guide provides step-by-step diagnosis and resolution with specific commands and code examples.
Symptoms
Typical symptoms and error messages when this issue occurs:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f8b2c1a3e2d (object 0x00000000d1a2b3c4, a java.lang.Object),
which is held by "Thread-2"Observable indicators: - Application logs show errors or exceptions - JVM crashes or becomes unresponsive - Related services may fail or timeout
Common Causes
- 1.Deadlock and hang issues are caused by:
- 2.Circular dependencies in lock acquisition
- 3.Missing timeout in wait operations
- 4.Incorrect thread synchronization
- 5.Resource starvation
Step-by-Step Fix
Step 1: Check Current State
jstack -l <pid> > thread_dump.txtStep 2: Identify Root Cause
jcmd <pid> Thread.print -lStep 3: Apply Primary Fix
```java // Use timeout with locks to avoid deadlock Lock lock1 = new ReentrantLock(); Lock lock2 = new ReentrantLock();
try { if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) { try { if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) { try { // Critical section } finally { lock2.unlock(); } } } finally { lock1.unlock(); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } ```
Apply this configuration and restart the application.
Step 4: Apply Alternative Fix (If Needed)
```java // Use ordered lock acquisition public class DeadlockPrevention { private static final Object lock1 = new Object(); private static final Object lock2 = new Object();
public void method1() { synchronized (lock1) { synchronized (lock2) { // Always acquire in same order } } }
public void method2() { synchronized (lock1) { // Same order as method1 synchronized (lock2) { // Prevents deadlock } } } } ```
Monitor JVM metrics after changes using JConsole or VisualVM.
Step 5: Verify the Fix
After applying the fix, verify with:
jcmd <pid> VM.info && jstat -gc <pid> 1s 5Expected output should show successful operation without errors.
Common Pitfalls
- Setting Xms larger than Xmx
- Ignoring JVM crash logs
- Not tuning GC for workload type
Best Practices
- Use G1GC for heaps > 4GB
- Set Xms equal to Xmx for production
- Monitor GC logs continuously
Related Issues
- Java OutOfMemoryError Heap Space
- Java GC Overhead Limit Exceeded
- Java JVM Crash Signal Error