Wednesday, January 5, 2011

Simple VisualVM gotchas with local processes

VisualVM is pretty awesome. However, for me it had a couple of slightly non-obvious gotchas the very first time I tried to use it to monitor local processes (ironically monitoring remote processes has always worked just as advertised). First, it only 'sees' processes using the same runtime environment automagically, second my copy seems to freeze if it tries to connect to a process that blocked on reading stdin (eg something like System.in.read()).


Problem 1: It only 'sees' processes using the same runtime environment
The documentation claims that "When you start Java VisualVM, a node for each local Java application is displayed under the Local node in the Applications window". As such I found it surprising when I launched a local Java process, started VisualVM to monitor it, and did not see my application listed under the Local node. WTF! 


It turns out that VisualVM only lists applications started using the same runtime. For example, if you start an application using C:\Program Files\Java\jre1.6.0_07\bin\java.exe and start VisualVM using C:\Program Files\Java\jdk1.6.0_07\bin\jvisualvm.exe it does NOT list your application. If you run your application using the copy of java.exe or javaw.exe from C:\Program Files\Java\jdk1.6.0_07\bin\ (the same version of the runtime visualvm is using) then all will be well.


This is simple enough once you know, and bloody aggravating until you figure out whats going on!


Problem 1.1: Eclipse might not use the same runtime environment as VisualVM
I typically use Eclipse to edit Java code and on occasion I find it helpful to launch a process from Eclipse and then monitor it with VisualVM. Naturally this doesn't work at all if Eclipse uses a different runtime environment than VisualVM. This section notes how to correct this problem.


If you want to start a process from in Eclipse it may be set (under Window>Preferences>Java>Installed JREs on Eclipse 3.6) to use the default JRE, similar to the setup below:


If the JDK is not listed we need to add it. Click add..., choose standard vm as type of JRE, and enter the JRE Home directory, similar to C:\Program Files\Java\jdk1.6.0_07. End result should be something similar to the following:


Next we need to make sure the project uses the appropriate system library. Right-click on the project, choose properties and then Java Build Path you should see the JRE System Library. If it is not set to the same JDK we will launch VisualVM from we'll need to change it. For example, you might see it is set to use a JRE as shown below:


In this case change it to the JDK by removing the JRE entry, then clicking Add Library, choosing to add a JRE System Library, and selecting the JRE to use, either by using Workspace default if you set the JDK as the default or by choosing Alternate JRE and explicitly specifying the JDK for the project.


Once the project is set to use the same JDK that is providing VisualVM you should find VisualVM automagically detects you process. Hooray!


Problem 2: It will freeze connecting to a process blocked on stdin
Having corrected problem 1 we can now see our process under the applications node, as shown below.




However, with the process blocking on a read of stdin double-clicking on the process put VisualVM into a seemingly indefinite (seemingly because after 60s I terminated it) wait, displaying it's helpful progress bar on the bottom right.


Unfortunately I don't know why this should be. If the process is blocked on a synchronization construct (most simply Thread.sleep()) VisualVM seems to connect fine, it just hates to bother a process waiting for user input.


This occurs consistently for me on Windows Server 2003 SP2, Java 1.6.0_23.

4 comments:

Roy Truelove said...

Useful - thanks!

sreenidhi said...

Informative.
Thanks.

libellule said...

Thanks so much for this post! I encountered all issues above, and you're the only source online that seems to notice this isn't as "magically" easy as the original documentation seems to suggest!

Unknown said...

Actually, I had to restart the process of interest so visualvm would pick it up.

Post a Comment