Every now and then I wonder why some page in my app is slow. Since connecting a profiler to the application running in production is not always an option I've written an emacs mode for analyzing jvm thread dumps.
You can take several thread dumps using build-in jstack tool (which is
cheap and doesn't affect application performance as a real profiling
does), put them in a folder and then run
thread-dump-open-dired-dir. The result is a master-details view of
thread names are on the left and the stacktrace of the choosen thread is on the right. You can filter and hide threads by their content.
To simplify analysis (no matter which tool you use) change the thread
name according to the job it is doing, e.g. add the page name into a
thread which renders it, so if the page is slow you can easily find a
corresponding thread by typing
/ page.html or something similar.
In my experience such a low-fi profiling is enough to get a high-level overview of the main performance problems.