February 8, 2011

Tools for monitoring JVM memory usage

This is more like a note to self than anything else because I have found over time that I often come back to my own posts to fish for little details.

OK so let's get right to it: got java-based app running somewhere, need to take a look at it. 2 options I like, in this order, are:

  1. VisualVM
  2. JConsole

Visual VM

I like this one best because it has had some more done on the UI which does make a difference. Also, when you have an issue that you suspect is going to be difficult to reproduce if you bounce the app, then VisualVM is nice because it doesn't require to restart the application. To get started, just start jstatd, it comes standard with your jdk. All you need is to create a file like /tmp/my.policy and put the following contents in it:


grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;

Then start jstatd by doing something like this:

nohup $JAVA_HOME/bin/jstatd -J-Djava.security.policy=/tmp/my.policy 2>&1 &


So the convenient part about this is that we didn't have to touch our application and we are now able to observe it.

Fire up VisualVM and point it to the host where you started jstatd and observe!

There is however a really nice feature in VisualVM that allows you to see where CPU time is spent in the observed application but VisualVM requires JMX access to the application which means that you will need to add some JVM options. Here they are:

-Dcom.sun.management.jmxremote.port=6789 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

It's not ideal and definitely not production worthy but it'll get you going when you want to tinker with your perfs in a sandbox.


JConsole is handy because of its ubiquity but it isn't nearly as nice as VisualVM.

First it always needs to have the JMX JVM options that are shown above. That may be a showstopper in and of itself. Especially for a production app that wasn't started with the JMX options for security concerns. I a lot of cases, you'll be flown in to put out a fire in a shop where there are best practices in place to block everything that isn't well understood (instead of trying to understand the uses and weigh the pros versus the cons) and you may also see situations where an issue is occuring on a live instance but you know that restarting the app will make it go away for an unknown amount of time, 8 hours, a week, a month, no clue.

Second, when you start a remote JConsole instance to start observing the application, you need to know the port. Now that was designed by guys who never went put out fires in real production situations with SLAs. Production or operations people NEVER let you get your hands on a live machine. In a lot of cases, you have to submit a request even if you only need to cat a config file to know what the JMX port was when it was configured some years back. At least with VisualVM, jstatd relays that information so it is able to discover all running java process on the machine it runs on and give you direct access to it. Sweet.

That was all for today ...