Short answer
Identify the hot OS thread first: top -H -p <pid> (Linux) shows per-thread CPU; convert the offending thread ID to hex and match its nid=0x... in a jstack thread dump to find the exact Java stack.
Explanation
Take several thread dumps a few seconds apart to see what is consistently running. Distinguish application hot paths (tight loops, inefficient algorithms, regex, serialization) from GC: if GC threads dominate, it is a memory/GC problem, so check GC logs. For precise hotspots use a sampling profiler like async-profiler (flame graphs) or JFR.
Common mistakes
- Restarting immediately.
- Not taking thread dumps to find the hot threads.