Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Tune Eclipse's startup performance with the Runtime Spy, Part 1

Getting started

Dan Kehn, Senior Software Engineer, IBM
Author's book cover
Dan Kehn is a Senior Software Engineer at IBM in Research Triangle Park, North Carolina. His interest in object-oriented programming goes back to 1985, long before it enjoyed the acceptance it has today. He has a broad range of software experience, having worked on development tools like VisualAge for Smalltalk, operating system performance and memory analysis, and user interface design. Dan worked as a consultant for object-oriented development projects throughout the U.S. as well as in Europe. His recent interests include object-oriented analysis/design, application development tools, and Web programming with the WebSphere Application Server. He co-authored The Java Developer's Guide to Eclipse.

Summary:  This article introduces the Runtime Spy, one of Core Tools available from Eclipse.org. The Runtime Spy is a perspective and set of views specifically designed to help you find and diagnose plug-in startup performance problems.

Date:  04 Mar 2004
Level:  Advanced
Also available in:   Japanese

Activity:  18131 views
Comments:  

Almost every day we hear of new companies adopting Eclipse as their application development platform of choice. With all these companies' products (not to mention all the Eclipse board member companies' products) potentially converging on the same installation, the risk of memory bloat and performance degradation is high. This article introduces a very helpful but not well-known tool, the Runtime Spy, to aid the plug-in developer. The Runtime Spy perspective is part pf the Core team's group of Spies and Tools (see Resources for a download link).

Note: The Core Tools run on Eclipse version 2.x only. At the time of this article's publication, they did not run on the Eclipse 3.0 drivers; bug 47518 has documented this problem.

Why Eclipse should start quickly

Eclipse's architecture is designed to enable the discovery of extensions to its environment at runtime. This architected extension capability allows many tools to integrate seamlessly into Eclipse. The Eclipse architects recognized early in the project that these extensions could not be defined programmatically in client code since the cumulative startup cost would become prohibitive as Eclipse integrated more and more extensions. Instead, these extensions are defined by plug-ins.

To avoid this startup cost while retaining flexibility, a plug-in statically defines its extensions in a manifest file. The plug-in manifest defines enough information to enable the Eclipse platform to postpone loading code while still recognizing the initial contributions of an extension. For example, the user interface extension points require enough information to render the initial user interface element (for example, the icon and tooltip text of a contributed toolbar button) so the platform can defer loading the plug-in code until the user actually chooses a menu option, selects a toolbar button, opens a preferences page, or starts a creation wizard. The initial cost of a plug-in is only the parsing of its manifest. The XML format parses quickly, and the result is saved to disk for the next time, so startup is not significantly affected as new plug-ins and extensions are defined. There are, however, means by which this benefit can be unwittingly defeated, thereby increasing startup time and memory consumption.

Fortunately, Eclipse plug-in developers can use the Runtime Spy perspective to help track down these problems. This article introduces the Core Tools plug-in and its Runtime Spy, plus some tidbits that describe its utility beyond what is already covered in the readme (see Resources). Part 2 of this article series describes the common programming mistakes that may lead to poor startup time. It also demonstrates how we used the Runtime Spy to improve the startup performance of IBM® WebSphere® Studio Application Developer version 5.1.1.


Installing the Core Tools

The installation is simple. Just download the Core Tools zip file and unzip it into your <inst_dir>\eclipse\plugins directory. Next decide whether you want to spy on your base Eclipse installation (use the -debug command line option) or whether you want to spy on your Run-time Workbench (use the Tracing page of its launch configuration. We'll return to this in "Spying on the Run-time Workbench"). For now let's go with the first choice: spying on your base Eclipse installation.

Another way to extend an Eclipse installation?

Copying a plug-in's files directly in a subdirectory of the plugins directory is easy, but did you know there is another way to tell Eclipse that you have another plug-in that should be merged with the base installation? This is done via link files; see "How link files extend an Eclipse installation" in the article "Put Eclipse features to work for you" for more details.

To begin, enable all the available Spy options by copying the sample .options file from the plugins\org.eclipse.core.tools_1.0.2 subdirectory into your <inst_dir>\eclipse directory. This will enable all options except those for class monitoring. To monitor class loading, you must list the packages or plug-ins that contain the classes that interest you in the plugins\org.eclipse.core.boot_1.0.2\trace.properties file. We'll come back to how you specify these in "Seeing what classes of a plug-in were loaded".

Next start Eclipse, and remember to specify the -debug command line option, which will read the .options file found in the <inst_dir>\eclipse directory. Alternatively, you can identify the location of the .options file as a parameter to the -debug option (for example, -debug file:d:\...\.options).


Spying on the Workbench

Let's assume you've installed the Core Tools files and restarted Eclipse. Since the -debug command line option is specified, you'll see some startup messages that were directed to stdout. When in debug mode, these are displayed in a separate Command Prompt window as shown in Figure 1.


Figure 1. Specifying the -debug option opens a Command Prompt window that shows stdout messages
Debug Command Prompt window

Now that everything is up and running, let's take a quick tour of the Runtime Spy's views. Keep in mind that the Spy runs in the same Workbench as the "spied" plug-ins, so some plug-in activation may occur through the natural course of using the tool itself. Usually this isn't an issue, since it only uses base functionality that will probably already be loaded or would have been loaded soon enough anyway. In the unlikely case that it does matter, remember that its views are only refreshed on demand, so the first time the Runtime Spy perspective is opened, it will show only those plug-ins that were active before its own activation.

Seeing what plug-ins were activated

Selecting Window > Open Perspective > Runtime Spy opens four views, as shown in Figure 2.


Figure 2. Runtime Spy perspective is composed of the Activated Plugins, Loaded Classes, Plugin Datasheet, and Stack Trace views
Runtime Spy perspective

If you forgot to specify the -debug option, you'll see the message "Plugin monitoring is not enabled" displayed in the Activated Plugins view. The Loaded Classes view will contain the message "Class monitoring is not enabled" since the default is no class monitoring. Capturing class loading information slows Eclipse, so you must list which classes you're interested in by specifying the package(s) or plug-in(s) that contain them. For now we're only interested in what plug-ins are loaded. Figure 3 shows the Runtime Spy's central view, Activated Plugins.


Figure 3. Activated Plugins view shown in the Runtime Spy
Activated Plugins

If you want memory usage statistics shown in the Runtime Spy views (Alloc, Used, and Rom Used columns), you must use the IBM Java Runtime Environment with J9 technology. This JRE is included with the IBM® version of Eclipse called WebSphere® Studio Workbench, which is available as a free download after you register with IBM PartnerWorld for Developers (see Resources for links). Remember to specify the J9 as an argument to the Java runtime environment (for example, eclipse -debug -vmargs -Xj9).

Clicking the first column heading, Plugin, changes the sort to ascending, descending, and ascending with grouping. The plug-ins grouped under the "+" symbol are the required plug-ins that were activated during the activation of the parent. When loaded plug-ins are grouped, the row's values are for the plug-in and all its child plug-ins. Use this ordering when you want to see the big consumers as a group.

The plug-in names followed by an asterisk are those that were loaded during startup. Despite what the name may suggest, the set of startup plug-ins marked with an asterisk in the Activated Plugins view will not include those that were loaded as a result of the Workbench processing its org.eclipse.ui.startup extension point. That is, the Workbench processes these extension contributions after the initial startup.

Of particular interest is the Order column. Clicking the column heading sorts the list of plug-ins in load order. If you want to quickly see what plug-ins are activated by a given action, select all the plug-ins beforehand (Ctrl+A), perform the action, return to the Activated Plugins view, and then select the Refresh button. The unselected plug-ins are those that were just activated. Alternatively, note the order value of the last plug-in that was activated before your action, and then afterward refresh to see those plug-ins that are ordered higher.

Seeing what classes of a plug-in were loaded

Classes of a plug-in are loaded on demand. You can potentially save memory and startup time by deferring these references or reducing the reference set of classes. The Loaded Classes view will help you see what classes of the selected plug-in have been loaded so far. To update the Loaded Classes view, select one or more plug-ins from the Activated Plugins list, and then select the Classes button. The loaded classes for the org.eclipse.jdt.core plug-in are shown in Figure 4, sorted in load order.


Figure 4. Loaded Classes view shown in the Runtime Spy
Loaded Classes

In addition to the plug-in activation order, I found this view useful to get a "big picture" of what classes and sequences a given action initiates by sorting in order of reference. The plug-in startup code is included in this list and gives you a good idea of the cost of executing it. The moral of that story is often "too much is done at startup."

Tracing why a class was loaded

To get a better idea of what led to the activation of a plug-in or the loading of a class, you first must have the trace options enabled for the plug-ins or packages of the classes that interest you. In this example, I created a traces.properties file containing the line packages=org.eclipse.jface.text. Then you need to:

  1. Select the org.eclipse.jface.text plug-in in the list of Activated Plugins.
  2. Update the Loaded Classes list by pressing the Classes button.
  3. Select the org.eclipse.jface.text.ITextViewer class.
  4. Select the Trace button to update the Stack Trace view.

This will display what code led to the classloader loading the class, and if it wasn't already done earlier, activating the selected plug-in, as shown in Figure 5.


Figure 5. Stack Trace view shown in the Runtime Spy
Stack Trace view

The top of the stack generally isn't interesting, since that's tracing the classloader code itself. The useful information is about midway down. In this case, the stack trace shows the ITextViewer class was ultimately loaded because the Runtime Spy perspective was opened, as shown at the bottom of the highlighted stack trace lines. The perspective opened its initial views, including the Plugin Datasheet view, which uses the JFace Text class TextViewer to display its data. While verifying the class during defineClass, the JVM found it needed ITextViewer as well because TextViewer implements this interface. As you can see, the JVM's runtime classloading can be nested quite deeply; for performance purposes you'll generally focus on the code leading up to the classloader calls, similar to the highlighted portion of the stack trace shown in Figure 5.

Tracing why a plug-in was loaded

The previous example showed why a specific class was loaded. You can also see why a given plug-in is loaded, but the reason for a plug-in's activation may not seem as obvious because the causes are indirect. Unlike a class that is typically loaded because it is referenced in another class' method (and has a corresponding import statement you can refer to), plug-ins are loaded as a consequence of some indirect reference. Recall that the goal is to avoid loading plug-ins until they are needed, so references to the plug-ins themselves are by:

  • Explicitly stated identifiers such as <import plugin="org.eclipse.ui"> in the plug-in manifest, or
  • Implied identifiers such as the exported packages in the runtime JARs for that plug-in

Both of these examples are highlighted in the extract from the "Hello, Eclipse" plug-in manifest, shown in Listing 1.


Listing 1. Sample extension point from "Hello, Eclipse"

				
<?xml version="1.0" encoding="UTF-8"?>
<plugin ...>
   ... lines omitted ...
   
   <runtime>
      <library name="hello.jar"/>
         <export name="*"/>
      </library>
   </runtime>

   <requires>
      <import plugin="org.eclipse.core.resources"/>
      <import plugin="org.eclipse.ui"/>
   </requires> 
   ... lines omitted ...

   <extension point="org.eclipse.ui.actionSets">
      <actionSet
         label="Sample Action Set"
         visible="true"
         id="hello.actionSet">
         <menu
            label="Sample &Menu"
            id="sampleMenu">
            <separator
               name="sampleGroup">
            </separator>
         </menu>
         <action
            label="&Sample Action"
            icon="icons/sample.gif" 
            class="hello.actions.SampleAction"
            tooltip="Hello, Eclipse world"
            menubarPath="sampleMenu/sampleGroup"
            toolbarPath="sampleGroup" id="hello.actions.SampleAction">
         </action>
      </actionSet>
   </extension>

The contribution of an action set to the org.eclipse.ui.actionSets extension point implicitly depends on the defining plug-in, the Workbench UI plug-in (org.eclipse.ui). The Workbench plug-in will read the plug-in registry, which includes this contribution to its org.eclipse.ui.actionSets extension, and create the appropriate action sets. The SampleAction class will not be loaded at this point and therefore neither will its containing plug-in. Instead the Workbench plug-in defines a delegate action to represent the choice in the user interface that waits until the user actually selects it before creating an instance of SampleAction to handle the response.

To create an instance of SampleAction, the action delegate calls the createExecutableExtension method of the plug-in registry instance IConfigurationElement that represents the <action class="hello.actions.SampleAction" ...> tag specified in our example manifest file. That's all well and good, but sometimes it isn't obvious looking at the resulting stack trace. Let's take a closer look at a more difficult example than the selection of a "Hello, Eclipse" menu choice. Figure 6 shows a typical activation that resulted from the processing of an executable extension. Now let's use the Stack Trace view to determine what caused it, following the same steps as before.


Figure 6. Stack Trace view showing executable extension activation
Stack Trace view

In this case, we see from the bottom of the highlighted portion of the stack trace that it all began with a double-click in the PDE's Plug-ins view. The default action handler responsible for handling the action requested the Workbench to open the Plug-in Manifest editor, which subsequently activated the org.eclipse.ui.editors plug-in. The highlighted portion of the stack trace shows only the code of the extension point processor because its reference to the Workbench plug-in classes, org.eclipse.ui, is indirect. After working through half-a-dozen similar stack traces, you'll recognize the important parts before and after the calls to IConfigurationElement.createExecutableExtension and quickly see who started it and what happened as a result. You can refresh the loaded classes by selecting the Classes button again and resort by load order to get a better idea of what happened after the plug-in's activation.

Other helpful views

Finally, the Plugin Datasheet view summarizes some interesting statistics, such as how many resources and extensions the plug-in defines, as shown in Figure 7.


Figure 7. Plugin Datasheet showing used resources
Plug-in Datasheet

This tracks the Resource bundle data that has been loaded via the IPluginDescriptor.getResourceString method and its variants. This summary information takes advantage of the fact that the Eclipse Platform Runtime provides its own classloader, and classloaders handle resource bundles in the same fashion as classes, so keeping track of resource data statistics is straightforward. The "not loaded yet" message refers to the fact that the plug-in registry is written to disk, and referenced portions of it are reloaded only as needed.


Spying on the Run-time Workbench

The previous sections covered spying on the base installation of Eclipse itself. More realistically, you'll want to spy on your test version of the Workbench, known as the Run-time Workbench. You can configure the instance of the Run-time Workbench you wish to launch by selecting Run > Run As... > Run-time Workbench and turning to the Tracing page as shown in Figure 8.


Figure 8. Setting the Runtime Spy options in the Tracing page
Tracing page

The debug options of the org.eclipse.core.boot plug-in are populated with the <inst_dir>\eclipse\plugins\org.eclipse.core.boot_2.1.1\.options file choices we discussed earlier. This defines the defaults that you'll more than likely want (everything on). However, if you want to take reasonably accurate performance measurements of elapsed time, you should minimize the number of active options, especially those that require taking a stack trace (that is, trace/pluginactivation etc.). Setting monitor/plugins to true and all others to false introduces little performance overhead.


Where to go from here

You can find a lot of information on Java performance tuning, but very little specific to Eclipse. This article introduced you to one of best tools for understanding and diagnosing startup performance problems related to plug-in activation. Before closing, it is worth noting some of the other useful diagnostic information that the Core Tools provide you:

  • The Plug-in Dependency perspective shows information similar to that shown in the Plug-in Registry view (accessible from Window > Show View > Other... > PDE Runtime > Plug-in Registry), but with an exhaustive listing of the dependent plug-ins of the selected plug-in.
  • Ever wonder what the workspace's .metadata directory contains? The Metadata perspective will help you walk its structure. It does, however, presume considerable understanding of the Workspace implementation.
  • The Resource Tools category of views presents useful insights into the inner workings of resource change listeners and resource deltas, builders, and more. The Resource, Delta, and Builder/Listener views are especially interesting for those learning the Workspace API. Select Window > Show View > Other... > Resource Tools) to access these views.

You can learn more about these tools in the Core Tools' readme (see Resources).

Part 2 of this article series will show how I used the Runtime Spy to diagnose several startup problems in WebSphere Studio Application Developer version 5.1.1. The subsequent improvements in startup performance varied from 11% to 37% depending on the active views and perspectives, demonstrating that knowing when and why your plug-ins are activated can help deliver on Eclipse's promise of a quick startup.

And just wait until you see version 6.0 of WebSphere Studio, where we'll really improve on startup performance!


Resources

About the author

Author's book cover

Dan Kehn is a Senior Software Engineer at IBM in Research Triangle Park, North Carolina. His interest in object-oriented programming goes back to 1985, long before it enjoyed the acceptance it has today. He has a broad range of software experience, having worked on development tools like VisualAge for Smalltalk, operating system performance and memory analysis, and user interface design. Dan worked as a consultant for object-oriented development projects throughout the U.S. as well as in Europe. His recent interests include object-oriented analysis/design, application development tools, and Web programming with the WebSphere Application Server. He co-authored The Java Developer's Guide to Eclipse.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Java technology
ArticleID=10924
ArticleTitle=Tune Eclipse's startup performance with the Runtime Spy, Part 1
publish-date=03042004
author1-email=
author1-email-cc=