views:

320

answers:

8

I have a big program in Java that uses multithreading. In some cases, the program starts using 100% of three cores of my eight core system. In normal use, the program use all cores at 1-2%. How can I find the class that's overloading cores?

+1  A: 

Try taking threads dump (see jps, jstack commands) and then see which methods are executed.

maximdim
Just looking at which methods are executed most frequently is not the same as finding out where the program spends most of its processing time.
Jesper
@Jesper: Do this some number of times like 10, then look for statements that are on multiple samples of stack. Then the fraction of samples containing a line is the fraction of time that line is responsible for, and would not be spent but for that line. The concept of "where the program spends its time" ignores the responsibility of method calls that cause time to be spent at lower levels.
Mike Dunlavey
@Mike My point is that you should measure how much time is spent in which parts of the program, not just how many times methods are called. You could have a method that is called 1,000 times but uses only 10% of the time, or a method that is called 100 times but uses 90% of the program's time. To optimize, you'd have to concentrate on the less frequently called method in such a case.
Jesper
@Jesper: You're right that the invocation count is almost meaningless. @maximdim is right that you should take stack dumps of the threads. Too many folks interpret the phrase "where the program spends time" as "where the program counter spends time". Programs "spend time" by calling other programs. Sampling the PC does not reveal this, but sampling the stack does reveal it, and large numbers of samples are not necessary.
Mike Dunlavey
... here's more on that subject than you probably ever wanted to know :-) http://stackoverflow.com/questions/1777556/alternatives-to-gprof/1779343#1779343
Mike Dunlavey
+14  A: 

Use a profiler such as the jvisualvm that is bundled with jdk-1.6.0_10

crowne
You may want to look for busy wait loop: `(while !done) {}`. Rarely will a correctly written thread be doing meaningful work at 100%, usually computation is occasionally blocked by I/O or synch. -- a good CPU usage graph should look slightly wavy.
Justin
+4  A: 

Use a profiler to figure out which thread(s) are using all of your CPU cycles, and the method(s) they are executing.

Justin Ethier
+3  A: 

If you are using Eclipse, you can use the TPTP profiling tool.

JProbe is a popular commercial profiler. You can download it and try it out for free. As crowne suggested, the profiling utilities packaged with Java 1.6 are pretty good as well.

dbyrne
+1  A: 

If you are going the commercial profiler route then I would recommend using Dynatrace.

CoolBeans
Ridiculous expensive both financial and in terms of overhead.http://williamlouth.wordpress.com/2010/05/25/the-java-application-performance-management-vendor-showdown/
William Louth
I am not sure how expensive it is but I found it more useful than JProbe. Dynatrace pure paths are very thorough and breaks the reports down nicely at the method level, sql level, api level. You can use the client profiler to see the java script execution, ajax call timings, rendering times, network times. I am sure it probably comes at a price. That's why I said if the OP is spending the money to get a commercial he could check it out.
CoolBeans
+1  A: 

If you are using Java over UNIX or some versions of Linux look into DTrace with Java.

Guy
Actually the dtrace probes for the JVM are pretty expensive at runtime.OpenCore Probes vs DTrace Java Probeshttp://opencore.jinspired.com/?page_id=190
William Louth
+6  A: 

The best solution is to use a profiler - that's what they're built for, and there's a great one bundled with Java 6.

Another (far from being as ideal a solution) is to run your program in the Eclipse IDE (if that's what you use) in debug mode. You can then look at the running threads. IF a lot of them are suspended, the one that is not might be your culprit. Force it to break (from the toolbar) and you can see where it is. There are many chances that you'll find a clear loop or busy waiting.

Uri
++ for your second paragraph, and you don't have to consider it as ideal, but that's the method I rely on, bar none.
Mike Dunlavey
A: 

Sampling is an dated, flawed and ill-suited solution for todays enterprise Java applications with hundreds of threads and deep call stacks. It has limited success in desktop applications - single threads and simplistic.

Its best to use an execution based profiler because for those with the thread dump stack blinkers on we are talking about CPU time not wall clock time and this is an intermittent issue.

Some further reading: http://williamlouth.wordpress.com/2009/01/16/profiling-sampling-versus-execution-part-2/ http://williamlouth.wordpress.com/2009/10/21/java-call-sampling-overhead-in-the-wild/

With an execution and strategy based metering solution this is pretty easy. Check out our Busy and BusyThread strategy docs on our OpenCore community website. These enable metering (measurement, profiling) automatically when such situations are detected.

http://opencore.jinspired.com/?page_id=772

William Louth
I've read through your stuff again, and my reaction is there are two orientations: measuring vs. finding. Much of your discussion is about minimizing overhead. For the purpose of finding problems, overhead would only be harmful if hid them. IME, problems nearly always consist of method calls that account for a large fraction of time (CPU *and* I/O) where those calls could be avoided. A deep stack is a rich hunting ground for such calls. If there are many threads, one has to find the threads that have the problems - they are in there. OTOH - asynchronous flow is harder.
Mike Dunlavey
William Louth