[RSS]

How can I profile NetBeans?

There are many possibilities how to profile Java applications and that can be applied to NetBeans profiling. For different task it can be good to select different ways because each of them has its strengths and weaknesses.

See also: DevFaqMemoryLeaks

To be able to profile an application it is usually needed to start it with a modified command that typically adds some (JVMPI or JVMTI) libraries, some classes to (boot)claspath, specifies options for profiling and often initializes profiling support before the application starts to run its code.

NetBeans profiler

Want to cover some typical activities like:

  • action execution (invoked from menu or by shortcut
  • window/dialog opening/closing
  • use of editor including tracking what happens in backgroud
  • startup

Analyzer

It is a sampling profiler working on Solaris and Linux (with limited functionality) that collects data during runtime. These data are later available for offline processing.

It provides some capabilities that are not available in other Java profilers namely timeline view. This view shows timeline for each thread visualising if the thread actually executes some code or not.

Download and install Analyzer tool

Performance Analyzer that is part of Sun Studio tools and can be downloaded from developers site.

Run the Analyzer

  • Set the environment. PATH should contain bin directory of Analyzer installation. LD_LIBRARY_PATH should similarly contain lib dir (and also /usr/lib/lwp if you want to run it on Solaris 2.8). Optionally you can also set MAN_PATH. Set the _NB_PROFILE_CMD:
export _NB_PROFILE_CMD='collect -p 1 -j on -S off -g NetBeans.erg  -y 38 -d /export/home/radim/analyzer

-p num stands for sampling period (on, hi, lo are also accepted), -j on turns on Java profiling, -y num determines the signal to trigger profiling on/off. -y num,r means that profiling will be resumed at the begining. Use man collect to get detailed explanation of all options.
  • mkdir /export/home/radim/analyzer (It is only need first time. Next experiments will be added.)
  • Install & start the IDE
  • Send signal 38 to Java process to start data collecting (kill -38 $pid)> Or use another signal like PROF (this works well on Linux).
  • Perform the analyzed activity
  • Send the signal again to stop profiling (there can be more evaluated periods during one run).
  • Shutdown the IDE.
  • Run the analyzer to evaluate the experiment in GUI environment: analyzer /export/home/radim/analyzer/NetBeans.x.er

Profiling hints

Startup: start with profiling enabled, send a signal when startup is completed. When sampling every 1ms it takes ~70 seconds instead of 40.

OptimizeIt and JProfiler

Use of OptimizeIt and similar tools based on JVMPI is limited to JVMs supporting this interface. Officialy Java 6 does not support it and there is a replacement - JVMTI.

The simplest way to run the IDE with OptimizeIt profiler was to use one of launchers from apisupport. One of them (nbopt.sh) is attached or they can be found in CVS history of apisupport

Trick to configure launching of NetBeans IDE from within OptimizeIt and JProfiler

The NetBeans is launched using the native launchers (at least on Windows XP) to get better control over the launching as well as supporting restarts after installation of module that require restart. However what this means is that it is hard to figure out what is the exact command line used to lauch the JVM that ultimately runs the NetBeans. Here is a tip for Windows XP platform to figure out what the exact command line is used. I use a tool called ProcessExplorer from formerly Sys Internals website. Using the ProcessExplorer tool it is possible to see the tree of processes that constitutes the NetBeans instance. The leaf of this tree is the JVM. By right clicking on the process entry and invoking the Properties dialog it is possible to look at the full command line that is used to launch the NetBeans instance. Here is a sample that I captured:

JVM Arguments:

-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade
-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense
-Xms32m
-Xmx128m
-XX:PermSize=32m
-XX:MaxPermSize=160m
-Dnetbeans.logger.console=true
-ea
-Dapple.laf.useScreenMenuBar=true
-Djdk.home=C:\Program Files\Java\jdk1.5.0_11
-Dnetbeans.home=C:\work\sun\cvsworkspaces\nbbuild\netbeans\platform7
-Dnetbeans.dirs=C:\work\sun\cvsworkspaces\nbbuild\netbeans\nb6.0;C:\work\sun\cvsworkspaces\nbbuild\netbeans\ide8;C:\work\sun\cvsworkspaces\nbbuild\netbeans\java1;C:\work\sun\cvsworkspaces\nbbuild\netbeans\apisupport1;C:\work\sun\cvsworkspaces\nbbuild\netbeans\enterprise4;C:\work\sun\cvsworkspaces\nbbuild\netbeans\profiler2;C:\work\sun\cvsworkspaces\nbbuild\netbeans\harness;C:\work\sun\cvsworkspaces\nbbuild\netbeans\extra
-Dnetbeans.user=C:\work\sun\cvsworkspaces\user.dir
-Dnetbeans.system_http_proxy=webcache.sfbay.sun.com:8080
-Dnetbeans.system_http_non_proxy_hosts=localhost;127.0.0.1;sfbay.sun.com;central.sun.com;czech.sun.com;sun.com;<local>
-Dsun.awt.keepWorkingSetOnMinimize=true

Classpath configuration:

C:\work\sun\cvsworkspaces\nbbuild\netbeans\platform7\lib\boot.jar
C:\work\sun\cvsworkspaces\nbbuild\netbeans\platform7\lib\org-openide-modules.jar
C:\work\sun\cvsworkspaces\nbbuild\netbeans\platform7\lib\org-openide-util.jar
C:\Program Files\Java\jdk1.5.0_11\lib\dt.jar
C:\Program Files\Java\jdk1.5.0_11\lib\tools.jar

Main Class:

org/netbeans/Main

Program arguments:

--branding nb

Enter these values in the respective fields of OptimizeIt and JProfiler settings/configuratiopn dialogs. I am also attaching a sample configuration(info) for OptimizeIt 4.2. You will have to adjust the paths to suite locations of JDK, NetBeans installation, user dir, proxy settings etc.

It has been my experience that by launching the profiled from withing the tool prevents the occasion tool crashes that happen when Attach mechanism is used. I do not have a good explanation for this though.

I think similar mechanisms e.g. wide output format ps command on Solaris and Linux may also show the full command line.

Other tools

Quite simple way how to measure time spent in some code is to wrap the code with

long t0 = System.nanoTime();
try {
... measured code
} finally {
long t1 = System.nanoTime();
System.out.println("action took "+(t1-t0)/1000000+"ms");
}

JVMTI is powerful interface that allows to write custom libraries that will track behavior of application.

DTrace is a comprehensive dynamic tracing framework for the Solaris™ Operating Environment. It is one of the few tools that allows to track activities running deeply in the system and analyze the system. Because there are also probes provided by Java VM and function like jstack it is also possible to map observed actions to parts of Java code in running application.

Tips and trick

Couple of links to docs about Java profiling, microbenchmark problems, netbeans tips

There are some good points where you can start your analysis for various types of tasks

  • Node pop-ups: interesting starting point is o.o.awt.MouseUtils$PopupMouseAdapter.mousePressed()

How to measure performance/responsiveness?

See What is UI responsiveness for overview.

Older Performance web page contains few links to documentation of one possible approach how to measure and profile responsiveness. This is based on use of modified event queue and patches classes from JDK.

Recently we changed the support a bit to avoid modifications of core JDK's classes and and use small utility library available in CVS of performance/performancetestutilities. This is used in current automated testing and can be used for manual checks too. To run such test:

  • Build performance/performancetestutilities project.
  • Copy the JAR file to netbeans/platform7/core
  • Start the IDE with -J-Dnetbeans.mainclass=org.netbeans.performance.test.guitracker.Main -J-Dguitracker.mainclass=org.netbeans.core.startup.Main
  • ... watch process output when you perform an action

Attachments

nb60.ois Info on nb60.ois 2631 bytes
nbopt.sh Info on nbopt.sh 674 bytes