Profiling UI Responsiveness

Author: Tomas Pavek
$Revision: $
$Date: 2009/10/29 16:50:16 $
Document history: available in CVS


We want to be able to profile user actions using OptimizeIt Profiler tool. More specifically, we want to profile performance of any user action between invocation of the action and finishing the action in the IDE. Technically, we just extend the Measuring UI Responsiveness technique by adding profiling capability. Please read the document first, as I often refer to it in this text.


Invoking profiler from a program can be done via special OptimizeIt API calls. Following methods from intuitive.audit.Audit class can be used:

  • public static void enableCPUProfiler(ThreadGroup aGroup)
  • public static void disableCPUProfiler(ThreadGroup aGroup)

These methods require specifying a ThreadGroup -- a group of threads that should be monitored. It is possible to profile just the current thread using the same methods without parameters, but it is better to monitor all threads, at least when profiling NetBeans.

We may also generate a snapshot, storing the profiling data in a file that can be opened in OptimizeIt tool later:

  • public static void generateSnapshot(int optionMask)

Following the general measuring technique, we may continue hacking java.awt.EventQueue. Hacking JDK directly brings problem with calling the Audit class methods -- they cannot be called directly, but just via reflection. The reason is that Audit class is not (and cannot) be on boot classpath when the program is running. If you add the API calls on exact places in the program's code, no reflection is needed, direct calls work normally.

To make the profiling invocation work, it's necessary to start the program in special audit mode, add some OptimizeIt libraries to classpath, and set some parameters. An example of starting NetBeans on Windows is shown below. Once the program is started, run OptimizeIt Profiler, attach it to the program, and you may start with profiling.

When to start and stop profiling? 

Let's follow the general responsiveness measuring approach. We want to start profiling when an user action occurs, and stop it when the action is complete (a paint occurs). The start and stop conditions should be specified better than just in simple time measuring, as it is not desirable to profile every user action, but only certain actions we are interested in. This can be done by watching only certain input events, so e.g. start profiling only when Enter is pressed. And when to stop profiling? As more paints can happen before an action completes, we cannot just stop with the first paint, but need a configurable paint count to be watched. To find out what number of paints is done for an action, we need to turn the profiling off temporarily to test the action. In case the number of paints cannot be reasonably defined, profiling could be stopped by pressing the starting key again. So we see that some further profiling configuration is needed to be done during runtime (more information below).

I will not describe how this all can be exactly implemented, you may look at the hacked code directly if interested:


Here are the steps to make it all work. The examples apply on Windows.

  • Get the diffs (for JDK 1.4.0 or for JDK 1.4.1), apply the changes to JDK sources.

  • Compile the changed sources.

  • Pack produced class files into a zip file, keeping the right package structure.

  • Modify 'ide.policy' file (in 'bin' directory of NetBeans) to grant security permissions to OptimizeIt libraries running together with NetBeans; e.g. add a section like:

    grant codeBase "file:///C:/OptimizeitSuite/OptimizeitSuite42/-" {
  • Start the IDE from the 'bin' directory using a special command with all parameters and switches as needed. In that command you must:

    • enable the audit system by -Xrunpri:dmp=1 switch,

    • add oibcp.jar file from OptimizeIt to boot classpath using -Xbootclasspath/a: switch,

    • add optit.jar file from OptimizeIt to classpath using -cp:a switch,

    • add the zip file with hacked JDK classes to boot classpath using -Xbootclasspath/p: switch,

    • add -dmp -enableAPI switches for audit system.

    The command then could look like:

    runide.exe -J-Xrunpri:dmp=1 -J-Xbootclasspath/p:D:\hacked_jdk\
               -cp:a C:\OptimizeitSuite\OptimizeitSuite42\lib\optit.jar
               -mainclass intuitive.audit.Audit -dmp -enableAPI org.netbeans.Main
  • Run OptimizeIt Profiler and attach it to the running IDE (using Ctrl+A).

  • After the IDE comes up, bring it to the situation when you can start the action to be profiled. Don't use Enter key as it starts the profiling by default.

  • Press ` key (the key below Esc key) to bring up a configuration dialog where you can set parameters like:

    • what key starts/stops profiling (Enter by default; other keys may be used too, e.g. right arrow for profiling tree node expansion, down arrow for combobox selection, Shift+F10 for popup menu invocation, etc),

    • for how many paints profiling runs,

    • what threads should be monitored,

    • whether to generate a snapshot in the end.

    Note you may also disable the profiling here (then only events and measured time are printed to console) and enable it later.

  • When ready to start the action to be profiled, switch to OptimizeIt and press the "Start CPU profiler" button. This does not start profiling, but makes the OptimizeIt "listen" to the calls from the application.

  • Switch back to NetBeans and invoke the action using the starting key. Profiler is started, monitoring the application until specified number of paints occurs, in which moment profiling is stopped (generating snapshot if set to do so).

  • Switch back to OptimizeIt and press "Stop CPU profiler" button -- and OptimizeIt will show the results.

That's all. You may repeat the profiling for various user actions just within one run of the IDE. The Profiling Configuration dialog should help.

Note: There is a problem with OptimizeIt 4.2 not stopping on API call when Instrumentation profiling is used. (It works without problems for Sampler profiling method.) The stop call is performed but profiling simply continues until Stop button is pressed in the OptimizeIt Profiler tool. This may distort the results. If facing this problem, set a snapshot to be generated. The snapshot is taken at the right moment, though profiling may continue. You can open the snapshot later in the OptimizeIt Profiler tool.


Please send comments to nbdev.

Project Features

About this Project

Performance was started in November 2009, is owned by tpavek, and has 91 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20160708.bf2ac18). © 2014, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
Please Confirm