Recently I had to analyse some code I'd written to work out why it was running so slowly. And it was running pig-in-the-mud slowly too, not just little-old-lady-going-shopping slowly. This thing was almost going backwards.
So I decided to bust out the profiler. It's my fervent belief that you shouldn't optimise code just because you think something might be slow; you have to know that it's slow. This is what a profiler excels at, and it sure beats System.out.println.
I'd previously had some exposure to JProfiler, which is excellent. Unfortunately though, it has a non-zero pricetag, which is often a barrier. I instead decided to investigate Eclipse's profiling solution.
The official one seems to be the Eclipse Test and Performance Tools Platform Project (there are others, but this one is officially hosted). This is also not a solution, because it is awful. It ran out of memory when I naively ran it with the default settings, and still ran out as I filtered the settings back to only profiling a few particular classes. In the end, the only way I could get it to work was to pare it back to only a handful of classes, which wasn't very useful.
The best solution out there is actually in NetBeans. If you hate the IDE, don't worry, you don't have to use it. Under the profiling menu, there is a command to attach to a remote process. Just fire your process up with the correct arguments -- NetBeans gives you these -- and your app will obediently wait until the profiler is started. Then you get profiling goodness in NetBeans (which works with the default settings), and the luxury of Eclipse. It's pretty much the best of both worlds, and unlike JProfiler it's free. Give it a try.