I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

The Best Kept Secret in the JDK: VisualVM

05.28.2009
| 133102 views |
  • submit to reddit

It's amazing the things that are right in front of you that you don't realise. VisualVM is probably the best example of this in the Java community. Everytime you go and update your JDK, you go straight to your IDE and capitalise on the new features provided. At least, that's what I thought I was doing.

I first read about VisualVM in an article Geertjan Wielenga wrote back in February of last year when the tool had it's third milestone release.  VisualVM could be the most important tool for Java developers, as well as being the best kept secret.  In a time where we're still trying to prove that Java isn't slow, this is the tool to help us keep the promise of performant Java applications. 

Blog About VisualVM for a Chance to Win $500 USD

 

VisualVM In A Nutshell 

VisualVM is a visual tool that integrates some of the commandline JDK tools and gives you powerful profiling capabilities. All for free! The commandline tools that it bundles up include jstat, JConsole, jstack, jmap and jinfo, which you get with your standard JDK distribution.

VisualVM will allow you to generate and analyze heap data, track down memory leaks, monitor the garbage collector and perform memory and CPU profiling, as well as being able to browse and operate on MBeans. While VisualVM runs on JDK6 it can monitor applications created since JDK1.4. 

For me, these features are critical. Up to now I've been using commercial tools like YourKit to run performance checks on my applications, but now I can get equivalent functionality from an open source tool. And who knows the JVM better than Sun?

How To Get VisualVM

The best part of VisualVM is that it's in your JDK bin directory already, if you've got any version of JDK1.6 since update 7. To run it, just click on the jvisualvm.exe icon.

All you need to do is click on the jvisualvm.exe and the application starts up. All Java applications running will be displayed on the right hand side navigation bar. Note that there is no need to register your application with VisualVM - it'll appear automatically. You can also view remote applications in this navigator.

 That unknown application (pid 5392) is Eclipse. 

 

Using VisualVM 

The list of features available is pretty impressive. VisualVM allows you to: 

  • Monitor application performance and memory consumption
  • Monitor application threads
  • Profile application performance and analyze memory allocation
  • Take thread or heap dumps
  • Analyze core dumps 
  • Save snapshots to analyze the application offline.

You'll find instructions on how all of these features work in our previous post on the topic, as well as in the VisualVM getting started documentation.

An IDE Comparison with VisualVM 

I wanted to do something different in my use of VisualVM, so I decided that I would do a comparison of the three leading IDEs. I did a fresh install of NetBeans 6.5.1 (JavaSE only version), Eclipse (for Java Developers) and IntelliJ IDEA (8.1.2).

The test is as follows: 

  • Run the Memory Profiler in VisualVM
  • Create a new project in the IDE
  • Create a simple class with a main method printing Hello World
  • Save the Memory Profiler results
  • Get a Heap Dump of the application
  • Get information from the Monitor view in VisualVM
  • Restart the IDE and using the CPU Profiler, perform the same steps in the IDE
  • Save CPU Profiler results

I realise that both the CPU and Memory Profiling could have been done simultaneously, but for the purpose of this article I wanted to keep them seperate. 

When I ran the IntelliJ tests I had to start it up with my own JDK rather than the IntelliJ one. I'm unfamiliar with the IDE, but I noticed it had to parse the files in the JDK when I created a new project with the JSDK.

Also, it's fair to note that I've just downloaded the default distributions of these IDEs, without trimming them down to the minimum for Java development.

Heap Dump

I found the best means for comparison across the applications was the Heap Dump. This is really easy to do - at any stage during the application run, right click on the application in VisualVM and select Heap Dump.

The criteria I will compare here is the total bytes and total classes.

NetBeans Heap Dump

NetBeans Heap Dump

Eclipse Heap Dump

Eclipse Heap Dump 

 IntelliJ IDEA Heap Dump

IntelliJ IDEA Heap Dump


IntelliJ :

  • Total Bytes:   76,582,715   
  • Total Classes: 14,368

Eclipse:

  • Total Bytes:   62,112,960
  • Total Classes: 11,428


NetBeans:

  • Total Bytes:   31,576,772
  • Total Classes: 10,583

It's clear here the NetBeans is the one that'll use up less of the heap using half the bytes that Eclipse needs. IntelliJ seems to need a lot more.

The Monitor View is also interesting to look at as your application is running. Here I simply looked at the threaded local classes. Eclipse almost hits 25K, IntelliJ gets closer to 27K, while NetBeans stays below 20K

NetBeans Monitor View

NetBeans Monitor View

Eclipse Monitor View

Eclipse Monitor View

IntelliJ IDEA Monitor View

IntelliJ IDEA Monitor View

 

Memory & CPU Profile Results

I noticed that when I started profiling, that I needed to wait for instrumentation to be performed on the classes and methods. For the IDEs this took a significant, but not unreasonable, amount of time.
Memory and CPU profiling isn't that useful for a comparison of products. Where profiling comes in handy is when you need to find where leaks exist in your application. Nevertheless, here are the results of the profiling for the IDEs.

It's interesting to look at the common objects between the IDEs. For example, byte[] is heavily utilized in NetBeans, but to a lesser extent in both Eclipse and IntelliJ. We do see a significant use of char[] on all IDE's

  • NetBeans : 19.6% of memory
  • Eclipse  : 31.6% of memory 
  • IntelliJ : 32.7% of memory

NetBeans Memory Profiler View

NetBeans Memory Profiler View

Eclipse Memory Profiler View

Eclipse Memory Profiler View

IntelliJ IDEA Memory Profiler View

IntelliJ IDEA Memory Profiler View

The CPU profiling shows where the majority of time was spent in execution. There's a big difference in the methods  that the IDEs spend there time on here

  • NetBeans spends most time on org.openide.util.RequestProcessor$Processor.run() - 58.1%
  • Eclipse spends it's time on java.lang.reflect.Method.invoke() - 45.5%
  • IntelliJ uses java.net.SocketInputStream.read() 38.7% of the time

NetBeans CPU Profiler View

NetBeans CPU Profiler View

Eclipse CPU Profiler View

Eclipse CPU Profiler View 

IntelliJ IDEA CPU Profiler View

IntelliJ IDEA CPU Profiler View


As a comparison, this tells us very little. But it is interesting to see the difference in how the IDEs work behind the scenes.

I must mention how easy this comparison was to do with VisualVM. I started it up before any of the IDEs and used the same instance all the way through, with the VisualVM registering each instance of the IDE automatically. 

IDE Integration 

Java developers are spoilt for choice when it comes to IDE's. It can be uncomfortable to step out of them to do any programming tasks - we've gotten used to it. Thankfully, there are plugin's available for all the popular IDEs, so you can work with VisualVM from the comfort of your favourite development environment, ignoring the command line. 

NetBeans integration is an interesting topic when it comes to VisualVM. VisualVM is actually the profiler that comes as part of NetBeans by default. In it's standalone format, it is a NetBeans RCP application, which can be further extended with other Netbeans modules. 

Eclipse and IntelliJ IDEA integration is available here. MyEclipse 7.5 also comes bundled with VisualVM plugins. As an Eclipse developer, I was interested to see how this would work out - after all the tool is based on the NetBeans platform. 

 

Eclipse Integration

First you'll need to download the VisualVM Launcher plugin, and extract it to you Eclipse home directory. When you open the Run Configurations dialog, you will get a choice of application launchers. The default launcher to use can be changed in the Preferences page depending on what you're running.

In my own setup I have chosen to use the VisualVM Launcher for Debug and the standard Eclipse Application Launcher otherwise. You can change these settings for applications, applets or Eclipse applications.

You will also need to specify a path to the VisualVM executable that you wish to use, and a path to the JDK.

 

That's the point where Eclipse integration ends, as it launches up an instance of VisualVM automatically and you can work from there. Perhaps in the future there will be some way of hooking directly into my IDE instance and profiling from there. 

Extending VisualVM

If all the features listed above aren't enough for your own requirements, you can roll your own VisualVM plugins. There are a number of API entry points available, as illustrated in the diagram below. 



The main entry points available are:

  • Tab extension. By default, VisualVM provides tabs with labels such as "Overview", "Monitor", and "Threads". You can create new tabs just like these. Optionally, your own tabs can be extendable so that others can plug subtabs into your tabs. Your tabs can either be available for all data sources in VisualVM or to specific types of data sources.
  • Subtab extension. Within tabs such as those listed above, you can provide new subtabs. However, this is only possible if the tab has been defined to be "pluggable", which is explained below. The following tabs are all pluggable: "Overview", "Monitor", "Threads", "Heap Dump", and "Host". When you create a new subtab, you can specify its position in relation to the other subtabs within the tab. Subtabs can either be available for all data sources or for specific data sources.
  • Menu extension. A data source, and its subnodes, can have one or more menu items added to their contextual menus.
  • Application type extension. By default, all applications visualized in VisualVM are treated equally, that is, they all have the same icons and tabs, except if a plugin is provided to provide additional functionality. You might also want to provide functionality for a specific application, which means that you would need to define a new application type. You can do this to do something as simple as provide a distinguishing icon for a running instance of your application. Alternatively, you might want to provide a lot of functionality, including graphs, to show the processing of your specific application.
  • Data source extension. The "Application" data source is only one of the types of data sources that can be monitored and managed in VisualVM. Another of the data sources is the "Host" data source, which lets you monitor and manage local and remote hosts. You might want to create new data sources, in situations where you want to monitor and manage a type of data source that VisualVM does not cater for by default.

There's a detailed page on the VisualVM site showing you how to create your own plugins for VisualVM.  It seems pretty straightforward, especially if you are familiar with the plugin development approaches in NetBeans or Eclipse.  And there are quite a few plugins available already through the VisualVM Plugins Center. To see these go to Tools/Plugins.

Considering how easy it is to get VisualVM (you have it already), and the extensible platform that it's built on, surely this will become one of those tools that you can't do without. I'm impressed with the way that it just picks up the applications that are running, instead of having to register with the profiler. In theory, you could have it running in the background all the time, while you perfect and relaunch your Java application.

It's something that you probably haven't taken much notice of before, but it's well worth taking it for a run and seeing if it helps you spot any weak performance areas in your application. 

 

 

Comments

Zviki Cohen replied on Thu, 2009/05/28 - 9:04am

AFAIK, it does not work on JVMs other than Sun, which means it does not support Mac OS X.

 

Steve Buroff replied on Thu, 2009/05/28 - 9:07am

jvisualvm bombs when I try to run it. I'm running 64 bit Vista and java 1.6.0_13.

Is there any chance it doesn't work on a 64 bit system? Please reply to:

sburoff@optonline.net

 

Thanks, Steve

James Sugrue replied on Thu, 2009/05/28 - 9:12am in response to: Steve Buroff

That's strange. According the the 1.1.1 release notes, 64bit Vista is supported : https://visualvm.dev.java.net/relnotes.html

I wonder if you'll have more success with the downloadable version? Let us know
James

 

 

Tom Wheeler replied on Thu, 2009/05/28 - 9:19am

As you note, VisualVM is built on the NetBeans Platform. That's actually what makes it an extensible platform -- any NetBeans Platform application is itself a new platform which can further be extended using the public APIs it exposes.

That VisualVM is a NetBeans Platform application means you could technically build your own platform application using nothing more than a recent version of the JDK.  I wish I could say this was part of some grand design by Sun, but I don't think many people (even inside Sun) realize this. Rather, I expect the people who developed VisualVM just wanted to create a modular/extensible application using Swing and found that the NetBeans Platform was the best way to achieve that.

Jiri Sedlacek replied on Thu, 2009/05/28 - 9:31am in response to: Zviki Cohen

Zviki: VisualVM 1.1.1 requires to run using JDK 6 or 7, supported are Sun JDK, Open JDK, Apple JDK and experimentally also HP-UX JDK (PA-RISC).

VisualVM can monitor applications running JDK 1.4.2 up, based on the version/vendor it provides various amount of information. These JDKs can be monitored using VisualVM: Sun JDK, Open JDK, Apple JDK, JRockit, IBM (using JMX) and HP-UX JDK (PA-RISC). When the VisualVM-Extensions plugin is installed, VisualVM can also monitor applications running the SAP JDK and Diablo JDK (BSD).

Jiri Sedlacek replied on Thu, 2009/05/28 - 9:43am in response to: Steve Buroff

Steve: It should work on your system. VisualVM logs important events into a logfile, you can find it in [userdir]/.visualvm/[version]/var/log/messages.log (on Windows Vista it's C:\Users\[username]\AppData\Roaming\.visualvm\[version]\var\log\messages.log). Typically the logfile is available from within the tool using Help | About | Logfile.

If your VisualVM doesn't "bomb" too early, the cause should be logged in the logfile. You can ask for a help on mailing lists feedback[at]visualvm.dev.java.net or users[at]visualvm.dev.java.net or file a bugreport at https://visualvm.dev.java.net/issues/enter_bug.cgi?issue_type=DEFECT.

Steve Buroff replied on Thu, 2009/05/28 - 9:45am in response to: James Sugrue

Nope. Running from Eclipse gives the same result. Bombs immediately.

Steve Buroff replied on Thu, 2009/05/28 - 9:55am in response to: Steve Buroff

I just tried it again and it works, both standalone and from eclipse. I don't know what I did

wrong initially but I apologize for the false alarm. Thanks for your help.

 Steve

Jaroslav Bachorik replied on Thu, 2009/05/28 - 12:19pm

As for the Eclipse integration - if you use the VisualVM 1.1.1 (or the upcomming jvisualvm bundled with jdk6u14 when it's available) the VisualVM instance will connect to the launched application automaticaly.

Alex Miller replied on Thu, 2009/05/28 - 11:14pm

@Zviki: You can run it on Macs with the SoyLatte OpenJDK 6 port.  If I recall, you do need to start up the vm with the jmx stuff enabled (like you used to do on 1.5):

-Dcom.sun.management.jmxremote

I've also heard that the next preview now available on the Apple Developer's connection does now have visualvm included but I haven't tried that myself.

 

Jakob Jenkov replied on Thu, 2009/05/28 - 11:54pm

This is the first time in a very long time that I have read any interesting news on Java, either here, or elsewhere! Thanks a lot for bringing my attention to VisualVM!

Brian Schlining replied on Fri, 2009/05/29 - 10:32am in response to: Zviki Cohen

That's not correct. It does run on Mac OS X. BTW, Apple's JVM is essentially Sun's JVM with some custom modifications made by Apple.

Andrew McVeigh replied on Sun, 2009/05/31 - 10:02pm

the cpu profile information is not particularly helpful in this incarnation of the visualvm. it doesn't seem to support method drill-down. perhaps through a plugin?

i.e. the article mentions that the CPU profile of eclipse shows that it spends 45.5% of its time in java.lang.reflect.Method.invoke(). however, this is surely just the top level reflection call from the eclipse rcp into the main plugin. if you were able to drill down you'd see that reflection is not the primary CPU usage.

Jiri Sedlacek replied on Mon, 2009/06/01 - 3:16am in response to: Andrew McVeigh

Andrew: You're wrong - VisualVM displays list of hot spots in live results, but once you take a snapshot you can see call trees and back traces - see the Profiling With VisualVM article.

Andrew McVeigh replied on Tue, 2009/06/02 - 6:55pm in response to: Jiri Sedlacek

>VisualVM displays list of hot spots in live results, but once you take a snapshot you can see call trees and back traces - see the Profiling With VisualVM article

thanks for the link, i'll have a look.

Andrew McVeigh replied on Tue, 2009/06/02 - 6:58pm in response to: Andrew McVeigh

>thanks for the link, i'll have a look.

I tried it last night -- it's fantastic.

are the pauses (I sometimes get pauses up to 20 seconds) due to classes being instrumented on the fly? is there any way to avoid this, perhaps by pre-instrumenting the classes? my application is a Swing app, with a large number of JDO instrumented classes.

Jiri Sedlacek replied on Wed, 2009/06/03 - 3:25am in response to: Andrew McVeigh

The initial pauses when you start the profiling are caused by instrumenting the classes, but even after all the classes are instrumented there's some overhead added by the profiler which slows down the application a bit.

I think you could improve the ~20 seconds pauses by fine-tuning the profiling parameters, the second part of the article describes it. But in general there's no way to pre-instrument the classes from VisualVM.

We want to address the performance problems during profiling by introducing a sampling performance profiler in some of the future VisualVM releases. Note that there's already a sampling memory profiler plugin available for VisualVM 1.1.1.

aldo gutierrez replied on Tue, 2009/06/09 - 4:42pm in response to: Steve Buroff

I have the same problem with Vista 64 bits an java 1.6_0_13 it bombs when trying to cpu profile

tomcat 5.5 or IntelliJ Idea 8.1.2 

Jane Luo replied on Thu, 2009/10/15 - 10:45am

I'm evaluating the visualVM monitoring tool. Question: Every time when I switch to CPU/Memory tab monitoring of my application, my laptop CPU got 100% full. What is the minimum requirement to use this tool, any one knows it?

EL Sun replied on Thu, 2009/10/29 - 2:29am in response to: Jiri Sedlacek

Hi Jiri and all

Thanks for sharing that with VisualVM-Extensions plugin, Diablo JDK is supported.

I have a VM with diablo jdk 1.6.0.07.02, FreeBSD 6.3-STABLE and amd64. There is a JBOSS application running on the VM. With the JVisualVM packaged with Sun jdk1.6.0_16 on my local PC box on Windows XP with SP2, I tried to add remote JMX connection but got error "Cannot connect using service:jmx:rmi:///jndi/rmi:3333//<ip>:3333/jmxrmi".

On the Jboss application I have the following to enable remote JMX, -Dcom.sun.management.jmxremote.port=3333 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

And I verified that port 3333 is accessible (telnet <ip> 3333) and thus not behind firewall.

The log in  C:\Documents and Settings\<user>\Application Data\.visualvm\6u14\var\log doesn't show any helpful entry for the connection failure.

I tried jconsole as well, and using suggestions from http://blogs.sun.com/jmxetc/entry/tracing_jmx_what_s_going, I was able to get the following log, but I am not even sure whether jconsole claims to support diabloJDK at all.

"Oct 28, 2009 11:04:02 PM RMIConnector connect
FINER: [javax.management.remote.rmi.RMIConnector: rmiServer=RMIServerImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:46608](remote),objID:[5e86c474:12479fb5730:-7fff, 4222350766315713530]]]]] connecting...
Oct 28, 2009 11:04:02 PM RMIConnector connect
FINER: [javax.management.remote.rmi.RMIConnector: rmiServer=RMIServerImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:46608](remote),objID:[5e86c474:12479fb5730:-7fff, 4222350766315713530]]]]] finding stub...
Oct 28, 2009 11:04:02 PM RMIConnector connect
FINER: [javax.management.remote.rmi.RMIConnector: rmiServer=RMIServerImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:46608](remote),objID:[5e86c474:12479fb5730:-7fff, 4222350766315713530]]]]] connecting stub...
Oct 28, 2009 11:04:02 PM RMIConnector connect
FINER: [javax.management.remote.rmi.RMIConnector: rmiServer=RMIServerImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:46608](remote),objID:[5e86c474:12479fb5730:-7fff, 4222350766315713530]]]]] getting connection...
Oct 28, 2009 11:04:03 PM RMIConnector connect
FINER: [javax.management.remote.rmi.RMIConnector: rmiServer=RMIServerImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:46608](remote),objID:[5e86c474:12479fb5730:-7fff, 4222350766315713530]]]]] failed to connect: java.lang.NullPointerException
Oct 28, 2009 11:04:03 PM RMIConnector close
FINER: [javax.management.remote.rmi.RMIConnector: rmiServer=RMIServerImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:46608](remote),objID:[5e86c474:12479fb5730:-7fff, 4222350766315713530
"Could you share any idea in debugging this further? I'd be happy to get it working with either VisualVM or JConsole.

Thanks so much!

E.Sun

Kathy Blackmore replied on Thu, 2012/02/23 - 3:48am

Any idea if there is a version of this tool that is compatible with the Mac OS? I have been coding using my Mac for years and never thought of searching for such a thing to improve my codes, thanks for sharing this!

Kathy - Cartridgeshop

Carla Brian replied on Tue, 2012/04/03 - 1:00pm

In Java Communitiy, many people are using visual basic. It is easy to understand and to use as well. - The Balancing Act Lifetime

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.