23

How can I find out who created a Thread in Java?

Imagine the following: You use ~30 third party JARs in a complex plugin environment. You start it up, run lots of code, do some calculations and finally call shutdown().

This life-cycle usually works fine, except that on every run some (non-daemonic) threads remain dangling. This would be no problem if every shutdown was the last shutdown, I could simply run System.exit() in that case. However, this cycle may run several times and it's producing more garbage every pass.

So, what should I do? I see the threads in Eclipse's Debug View. I see their stack traces, but they don't contain any hint about their origin. No creator's stack trace, no distinguishable class name, nothing.

Does anyone have an idea how to address this problem?

jschmier
  • 15,458
  • 6
  • 54
  • 72
EoH
  • 821
  • 6
  • 9

5 Answers5

15

Okay, I was able to solve (sort of) the problem on my own: I put a breakpoint into

Thread.start() 

and manually stepped through each invocation. This way I found out pretty quickly that Class.forName() initialized lot of static code which in return created these mysterious threads.

While I was able to solve my problem I still think the more general task still remains unaddressed.

EoH
  • 821
  • 6
  • 9
10

I religiously name my threads (using Thread(Runnable, String), say), otherwise they end up with a generic and somewhat useless name. Dumping the threads will highlight what's running and (thus) what's created them. This doesn't solve 3rd party thread creation, I appreciate.

EDIT: The JavaSpecialist newsletter addressed this issue recently (Feb 2015) by using a security manager. See here for more details

MORE: A couple of details for using the JavaSpecialist technique: The SecurityManager API includes "checkAccess(newThreadBeingCreated)" that is called on the thread creator's thread. The new thread already has its "name" initialized. So in that method, you have access to both the thread creator's thread, and the new one, and can log / print etc. When I tried this the code being monitored started throwing access protection exceptions; I fixed that by calling it under a AccessController.doPriviledged(new PrivilegedAction() { ... } where the run() method called the code being monitored.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
1

When debuging your Eclipse application, you can stop all thread by clicking org.eclipse.equinox.launcher.Main field in the debug view.

Then from there, for each thread you can see the stack trace and goes up to the thred run method.

Sometimes this can help and sometimes not.

As Brian said, it a good practice to name threads because it's the only way to easily identify "who created them"

Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
  • 1
    As I already stated I did this and it's of no help in this case. And I repeat: I *did not* create these threads. – EoH Aug 04 '09 at 13:06
  • As I said, I think the name is the only quick solution for that. Since the "creator" of these thread didn't named it I think the solution you mentioned (debuging Thread.start()) is the only one .... – Manuel Selva Aug 04 '09 at 13:40
1

For local debugging purposes, one can attach a debugger to a Java application as early as possible.

Set a non-suspending breakpoint at the end of java.lang.Thread#init(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long, java.security.AccessControlContext, boolean) that will Evaluate and log the following:

"**" + getName() + "**\n" + Arrays.toString(Thread.currentThread().getStackTrace())

This will out the thread name and how the thread is created (stacktrace) that one can just scan through.

Kenston Choi
  • 2,862
  • 1
  • 27
  • 37
  • 1
    That's a nice and unobtrusive solution to keep track of threads. I had to look up how to do that in Eclipse. Debuggers apparently use different names for the concept non-suspending breakpoints. In Eclipse they are called "tracepoints". They basically seem to be regular conditional breakpoints that just call printf as condition - but the condition doesn't return true, so they never suspend. Another common name for them is "watchpoints" – kapex Apr 14 '23 at 15:03
0

Unfortunately it doesn't. Within Eclipse I see all the blocking threads, but their stack traces only reflect their internal state and (apparently) disclose no information about the location of their creation. Also from a look inside the object (using the Variables view) I was unable to elicit any further hints.

EoH
  • 821
  • 6
  • 9
  • "unfortunately it doesn't" -- what's "it" and what doesn't it do? – Jason S Aug 04 '09 at 13:29
  • @EoH, I assume you wanted to comment but sent an answer instead. Please remove your answer and make a comment. (I don't know how this wasn't downvoted yet )))) – superM Dec 18 '12 at 11:57