How to Debug Java Applications Like a Pro

Views: 0

Why Debugging Isnโ€™t Just Fixing Bugs

Bobโ€™s Spring Boot app is acting up:

  • Itโ€™s slow under load
  • It hangs randomly
  • CPU is spiking without obvious cause
  • Memory usage grows over time

Traditional logging wonโ€™t cut it. Bob needs to see what the JVM sees.

Letโ€™s level up from โ€œprintln debuggingโ€ to JVM introspection.

Tools of the Trade

1. Thread Debugging with jstack

Use when:

  • Your app hangs
  • CPU is high
  • You suspectย deadlocks or thread leaks

Example:

jstack > thread-dump.txt

Then open with tools like:

  • FastThread.io
  • IntelliJ / VisualVM
  • Look forย Blocked,ย Waiting, orย RUNNABLEย with high CPU

2. Heap Analysis with jmap & VisualVM

Use when:

  • OutOfMemoryError
  • Memory leaks
  • GC isnโ€™t reclaiming memory

Dump heap:

jmap -dump:live,format=b,file=heap.hprof

Open in:

  • VisualVMย (free)
  • Eclipse MATย (Memory Analyzer Tool)
  • YourKitย (commercial)

Look for:

  • Dominator trees
  • Retained objects
  • Unclosed resources

3. CPU Profiling with Java Flight Recorder (JFR)

Use when:

  • CPU is spiking
  • Methods are slow
  • You need real-time JVM profiling

Record a flight:

jcmd JFR.start name=debug settings=profile filename=recording.jfr

Let it run for a while, then:

jcmd JFR.stop name=debug

Open .jfr file in:

  • JDKMission Control (JMC)
  • View: hot methods, GC, memory, threads

Very low overhead โ€” safe in production!

4. Async Profiler + Flamegraphs

Use when:

  • You want visual flamegraphs
  • Youโ€™re debugging CPU usage or method hotspots

Run with:

./profiler.sh -d 30 -f cpu.svg

Opens an interactive flamegraph:

  • Wide = time spent
  • Tall = stack depth

Perfect for understanding hot code paths and performance bottlenecks.

5. Live Debugging with VisualVM

Best for:

  • Quick CPU/memory snapshots
  • Watching GC in real time
  • Sampling threads

Install VisualVM and attach to your running app:

  • Viewย heap usage
  • Trackย thread states
  • Takeย heap/thread dumps

Free, built into most JDKs
Great for dev/staging environments

6. Live Instrumentation with BTrace

Want to trace method arguments and return values in a running app?

Example trace:

@OnMethod( clazz=”com.myapp.Service”, method=”process”, location=@Location(Kind.ENTRY) ) public static void onEnter(@Self Object self, String arg) { println(“Entering with arg: ” + arg); }

Zero restart
Live instrumentation
Perfect for debugging unknown behavior without changing code

Bobโ€™s Debugging Flow

Bob doesnโ€™t guess. He observesrecords, and targets the problem like a real JVM detective.

Pro Tips

  • Combine JFR + async-profiler for full insight
  • Always run withย -XX:+HeapDumpOnOutOfMemoryErrorย in prod
  • Use sampling instead of tracing in production
  • Avoidย -agentlib:hprofย (deprecated & heavy)

Debugging like a pro means:

  • Observing the JVM itself
  • Using the right tool for the job
  • Visualizing CPU, memory, and threads โ€” not guessing

Bob can now:

  • Catch memory leaks
  • Profile hotspots
  • Reduce latency
  • Untangle thread issues

Find us

linkedin Shant Khayalian
Facebook Balianโ€™s
X-platform Balianโ€™s
web Balianโ€™s
Youtube Balianโ€™s

#javadebugging #springboot #jvmprofiling #memoryleak #javaflamegraph #visualvm #jfr #asyncprofiler #threadanalysis #performancetuning

Visited 26 times, 1 visit(s) today
Translate ยป