As ckhan mentioned,
jstack is great because it gives the full stack trace of all active threads in the JVM. The same can be obtained on stderr of the JVM using SIGQUIT.
Another useful tool is
jmap which can grab a heap dump from the JVM process using the PID of the process:
jmap -dump:file=/tmp/heap.hprof $PID
This heap dump can be loaded in tools like
visualvm (which is now part of the standard Oracle java sdk install, named jvisualvm). In addition, VisualVM can connect to the running JVM and display information about the JVM, including showing graphs of internal CPU usage, thread counts, and heap usage - great for tracking down leaks.
jstat, can collect garbage collection statistics for the JVM over a period of time much like vmstat when run with a numeric argument (e.g.
Finally, it is possible to use a Java Agent to push instrumentation on all methods of all objects at load-time. The library
javassist can help to make this very easy to do. So, it is feasible to add your own tracing. The hard part with that would be finding a way to get trace output only when you wanted it and not all the time, which would likely slow the JVM to a crawl. There's a program called
dtrace that works in a manner like this. I've tried it, but was not very successful. Note that agents cannot instrument all classes because the ones needed to bootstrap the JVM are loaded before the agent can instrument, and then it's too late to add instrumentation to those classes.
My Suggestion - start with VisualVM and see if that tells you what you need to know since it can show the current threads and important stats for the JVM.