Using JConsole to monitor ColdFusion's JVM

Posted by Dan on Dec 12, 2007 @ 5:16 PM

If you're experiencing problems with your server or just want a better idea of how your server's using memory, the Java JDK provides an excellent monitoring tool called JConsole.

JConsole comes included in the latest Java JDK and can be found in the JDK_HOME/bin folder (where JDK_HOME is the installation folder for your JDK). ColdFusion does not come with the JConsole application, so you'll need to download and install the JDK on a machine that has access to your server (if you do not already have a JDK installed.) JConsole does not need to run on the ColdFusion server, you can connect to a remote server so you can run the application right from your Workstation.

In order for JConsole to connect to your server, you'll need to edit your CFUSION/runtime/bin/jvm.config file (where the CFUSION is your ColdFusion installation folder.) Before editing the jvm.config file, always make a backup.

You'll want to add the following arguments to your java.args property:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<port>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

The arguments should all be on a single line and then go after the -server argument—which should always be the first switch in the arguments line. (Thanks goes to Steven Brownlee's Blog for the above argument information.) Also, make sure to change <port> to an open port on your server. I used port 9500.

Make sure to read the Using JConsole that Sun has published. It'll walk you through configuration, connecting and how to use the tool. JConsole will provide lots of really good information about the state of your server. Here's what the application looks like:

Categories: HTML/ColdFusion, Java

13 Comments

  • Good stuff Dan. I'm wondering if you hit the same issues I did: first, I had to ensure that CF was running under the same account as was used to start up jconsole. This one baffled me for a while... I was getting an "unable to map user to vmid" error. The 2nd bugaboo was getting hooked into the specific CF process. With java, I've always used jconsole with a URL; but with CF, I couldn't get that working. Turned out to be as simple as just plugging into the PID (i.e. jconsole 4567).

    Thanks for sharing!
  • Thanks for this - I was trying to get this up and running last week but didn't realise you have to add the jvm args into the jvm.conf file! Doh!
  • Glad you found Jconsole useful Dan. Sometime when you have time I should walk you through all the tools I use
  • @Marc - How do you know what PID CF is running under?
  • @Troy - you can look at the Event Viewer and look for the mesage after CF started.
    Somthing like:
    "The JRun cfusion_3 service for the "cfusion_3" server was started. PID is 1308."
    Where "cfusion_3" is the instance name and commonly the service name too.

    Marco.
  • Just wanted to add that I was able to successfully set this up also thanks to your blog...

    As soon as I changed the JVM config settings as you directed and restarted CF, I went to another server where I had the JDK installed, fired up JConsole and then under "Remote Process" entered 10.10.10.40:9500 and was able to connect to my server...

    Thanks so much!
    Patrick
  • I'm going to add this here as well, for posterity.

    I use Linux VMs as servers, and I needed to also set:
    -Djava.rmi.server.hostname=<hostname>

    In the JVM args, to allow the RMI invocation to work over my VM NAT network.

    See: http://blogs.sun.com/jmxetc/entry/troubleshooting_... for more information.
  • Good to see you share this, Dan. Just a couple of other thoughts for people coming here.

    As for the point Marc made about the user for jconsole needing to be the same used to start CF: yes, Windows folks may get tripped up using this if they have CF running as a service under the System account (the default) but they run the jconsole from their command line. Your choices are either to run CF from the command line as well, or change CF to run under your account instead. Of course, there's always the chance that CF will operate differently under a less privileged account, so keep that in mind.

    As for the setting of -Dcom.sun.management.jmxremote.authenticate=false, we should suggest people be aware of what that's about. It disables any requirement to provide authentication, and by enabling remote access (the -Dcom.sun.management.jmxremote.port), you're opening a potential security hole. You can learn more about enabling security (including SSL) here: http://java.sun.com/j2se/1.5.0/docs/guide/manageme.... If you start CF from the command line, you don't need to enable the remote port (can then be accessed only by a local jconsole on the same machine). Running CF from the command line also opens the door to using other tools like jmap, jstack, and so on, which might otherwise fail to work if CF is started as a service (I've found).

    Troy, about finding the pid's for CF, besides the event viewer suggestion you can also use the jps command to list what java processes are running on your machine.

    Hope that's helpful.
  • Thanks for the encouraging blog posting of over two years ago.

    I have been recommended to the jConsole tool several times over the last week as I try to debug a strange CPU spike|spinning issue that seems to involve one of our ColdFusion 8 instances on our Windows 2003 web server.

    I wanted to ask for clarification, as I failed the first time I tried to tie jConsole into the ColdFusion|Jrun4 jvm, are the -Dcom.sun.management.jmxremote java arguments expected to work with the JRun4 out-of-the-box jvm that installs with ColdFusion 8?
  • @Ian:

    Yes, they should work fine. CF uses a standard Sun JVM, so there's nothing special about it.

    However, I seem to recall either the order of the arguments being important or their being a conflict with -XX:+UseParallelGC. Here's what my java.args line looks like from my dev server:

    java.args=-server -Xms1024m -Xmx1024m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9500 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=5005,suspend=n -DJINTEGRA_NATIVE_MODE -DJINTEGRA_PREFETCH_ENUMS -Dsun.io.useCanonCaches=false -XX:MaxPermSize=256m -Dcoldfusion.rootDir={application.home}/../ -Dcoldfusion.libPath={application.home}/../lib -Dcoldfusion.classPath={application.home}/../lib/updates,{application.home}/../lib,{application.home}/../gateway/lib/,{application.home}/../wwwroot/WEB-INF/flex/jars,{application.home}/../wwwroot/WEB-INF/cfform/jars

    I have some additional arguments that I use for SeeFusion, so you'll want to optimize your arguments for your environment.
  • @Dan

    Thank you for your prompt response the day before yesterday. The first thing this morning (after spending a day in bed recovering from the cold or flu), I tried the java arguments again and they worked. Following your example I put them in the same position in my list. But I suspect I originally had the syntax wrong the first time I tried it. I did not have the dash "-" in front of each one and I don't think I had the basic "-Dcom.sun.management.jmxremote" at the beginning, just the .port, .authenticate, and .ssl arguments.

    One followup question, that you may know. We have a multi-home configuration on our servers. So in putting these arguments into the jvm.config file, all the instances will then be communicating over the same port. Does the jConsole tool distinguish the separate JRun instances.
  • And I answer my own question with a failed experiment.

    Each instance needs it's own port thus one must make sure that each instance uses a different jvm configuration file.
  • I'm trying out jconsole for the first time and I came across this page. It's been very helpful. I had difficulty connecting jconsole to my local CF, probably due to them running under different accounts like Charlie said. But I was able to connect 'remotely' to 127.0.0.1:9500.

Add Comment

Leave this field empty