Or: "My Java takes a long time / runs out of memory, how come??"
So, I have a Java application that is running a bit slow.
I could go all the way and throw
VisualVM after it to have a nice GUI to try and profile it with, but the application is running at a remote server and I don't feel like opening up RMI ports and what not.
Quick and Dirty Profiling
To use HPROF to quickly get an image of what is taking all the time in the application we run the Java VM with the following params:
java -agentlib:hprof=cpu=samples RecursiveClustering
This will tell HPROF to collect CPU usage information by sampling threads. We will then have an output file
java.hprof.txt containing the result of the analysis we have asked for.
I have included a sample from my profiling here:
CPU SAMPLES BEGIN (total = 21079) Mon May 20 12:31:57 2013 rank self accum count trace method 1 27.80% 27.80% 5859 300304 java.lang.StrictMath.acos 2 24.52% 52.32% 5169 300275 java.net.SocketInputStream.socketRead0 3 6.49% 58.81% 1369 300349 java.lang.String.length 4 5.19% 64.01% 1095 300407 java.util.regex.Pattern$Branch.match 5 3.57% 67.58% 753 300315 java.util.Vector.indexOf 6 3.51% 71.08% 739 300311 java.util.Vector.contains 7 3.04% 74.13% 641 300308 DBscanDistanceMatrix.getNeighboursWithinRange 8 2.25% 76.38% 475 300443 java.util.regex.Matcher.getTextLength 9 1.75% 78.13% 368 300446 java.util.regex.Pattern$Curly.match 10 1.43% 79.56% 302 300416 java.util.regex.Pattern$Start.matcho
We can se that
java.net.SocketInputStream.socketRead0 are responsible for 52% of the cpu time. Maybe I try not calling
acos so much, or optimizing my database. :)
These numbers are created by sampling the threads. If we wanted a more accurate result we could use
This option injects code into every method entry and exit, keeping track of exact method call counts and the time spent in each method.
Very precise and very slow..!!
HEAP Dump - using HAT
HPROF is also able to create heap dumps. We can enable this using the following:
java -agentlib:hprof=heap=dump RecursiveClustering
The resulting text file is big and scary! So instead we fill use the following, and tell HPROF to format the result as binary data.
java -agentlib:hprof=heap=dump,format=b RecursiveClustering
Now we are able to use the tool called
jhat - Java Heap Analysis Tool.
This will start a webserver on the machine allowing us to browse the java classes and objects instances using memory when the dump was created.
A nice and clean explanation of profiling with HPROF by R.J. Lorimer: