Java's available sets of tools for this kind of stuff is woefully inadequate, but here's what I use:
NetBeans Profiler: Not bad for what it does, Memory Stack Allocation tracers are nice, but I haven't been able to get it to profile just certain methods in a selected class. It also seems pretty stable over long periods of time and doesn't interfere too much with the running of the application.
JMP: I started using this for it's heapwalking abilities. Other things I've tried are hprof and hat... but with no success at all. JMP is not stable over long periods of time. It will frequently just decide to take a vacation even if you aren't monitoring anything, but for tracking down things like object owner chains, it's very good.
Haven't done any actual performance profiling, so that's the extent of my knowledge.