Here is how you do it.
- Get the application running under load (or if its a single threaded long running operation, just let the operation get started).
- Send a BREAK signal to the Java process. In Unix/Linux, you can do this with kill -3 ProccessId. In Windows, you can do this by using a program called SendSignal (Note I don't endorse this tool, but happen to find it useful).
You'll see the process start to consume exactly one CPU in the system (on a uniprocessor box, 100% CPU, on a 4-way box, 25% CPU, for example). During this time the JVM is doing its job collecting up all the information for the core. At the end it will dump the core to the working directory of the application. Once it is done (could take some time) the CPU will go back to normal.
- Let the process continue for a little while, so the application gets back into its normal state.
- Then repeat the previous steps starting with the BREAK signal three or more times (the more the better).
- Look at the information in the thread dump section (search for "Full thread dump") of the Java core and make sure it looks similar in all three (or more) core dumps. If so, you should have enough certainty to trust what you see in the core dumps.
In a future post, I'll talk about what to look for in the Full Thread Dump, but to get you started, if you see the same method repeatably on the top of the stack of multiple threads, that is what you want to go after first.
In the last two months, I used this approach successfully to find problems in an application server application (bad third party libraries) and a migration script (bad algorithm for handling large amount of data). Both showed rather clearly what needed to be fixed in the program. Also, since this comes with Java, you need no tools to use the "poor man's profiler".
If you have questions or if you find this tip useful, please post a comment on this topic.