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 developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

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 2

Winning the shell game

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:  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. This article describes how to find common programming mistakes that may lead to poor startup time and how to correct them. Included is a case study demonstrating how the Runtime Spy was used to improve the startup performance of IBM® WebSphere® Studio Application Developer. The previous article, Part 1, introduces the Runtime Spy.

Date:  16 Mar 2004
Level:  Advanced

Activity:  7923 views
Comments:  

After reading Part 1 of this series, you should have a general idea of how the Runtime Spy can help you locate startup trouble spots. Let's turn to some specific examples of how to use it to reduce your plug-in's startup time. To make it more interesting, we'll look at some problems that were corrected with the help of the Runtime Spy as part of the performance improvements of IBM WebSphere Studio Application Developer.

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.

Helping Eclipse start quickly

The two general goals for improving the startup performance of an Eclipse-based application are:

  1. Defer plug-in activation until as late as possible
  2. Minimize the amount of work involved in activating your plug-in

A common tenet of both goals is defer code execution where possible. Here are some ways you can do this:

  • Don't load your plug-in
    How? First and foremost, follow the lead of Eclipse's own plug-in extensions. Recall that many of the Eclipse extension point definitions require the contributor to statically declare enough information so that loading code can be deferred until the requested action is needed. This idea is fundamental to the Eclipse architecture and embodied in the plug-in manifest file declarations. Your own extension point definitions should embrace this approach.

  • Reduce class loading during plug-in initialization
    The most common culprits are references within the Plugin.startup method. Many plug-ins override this method to perform their initialization. The ideal solution is often for your plug-in to defer its initialization until the user requests a specific action of your product. Otherwise, minimizing the number of referenced classes and plug-ins is the next best choice. In either case, the Runtime Spy can point to those that might be taking too much time or triggering the activation of too many other plug-ins.

  • Reduce CPU usage during plug-in initialization
    Again, the most common cause points to code within the plug-in's startup method or code called by it. Lazy initialization of memory structures will save CPU time and may defer the activation of other plug-ins. Another possibility is to fork a separate low-priority thread during startup to perform initialization when the system is idle, although this choice requires more care to handle synchronization.

By deferring the activation of a plug-in, the user is given the impression of a zippier product. It may well be that the cumulative CPU usage is the same, but having it spreading it out in small chunks over a long period is less noticeable than paying the brute cost upfront. A delay is especially objectionable if it occurs at the first invocation (that is, starting your product, or opening the first perspective, editor, or view), as this is the very moment the user is focused on getting work done and not feeling especially patient.


Reintroducing the Runtime Spy

The Runtime Spy gives you the basic statistics for tracking each of the three ways of speeding up startup, as shown in Figure 1.


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

Minimizing the number of items in the Activated Plugins view is your number-one goal. Of those that do appear in this list, make it your number-two goal to minimize the number of items in the Loaded Classes view. The Startup time column in the Activated Plugins view will point you to the big hitters. Selecting the Trace button from the Activated Plugins view will update the Stack Trace view to show you why a plug-in was loaded, and selecting the Trace button from the Loaded Classes view will show you why a class was loaded.


Spying on WebSphere Studio

Let's begin with examples of how to use the Runtime Spy to diagnose and correct a startup coding error. As you'll see, the corrections will not "improve" performance in an absolute sense but rather defer startup costs, giving the user the perception of an overall faster product. This is something that the base Eclipse product does very well, staging its startup costs in little chunks as you use it. This is the cornerstone of Eclipse's deferred plug-in load strategy.

To first survey the situation, let's start Studio with only the Runtime Spy perspective open. This should give a near-minimum load of plug-ins and the fastest startup, as shown in Figure 2.


Figure 2. Minimal activated plug-ins at startup
Minimal activated plug-ins at startup

Tip: Seeing the newly activated plug-ins at a glance

Pressing the Refresh button doesn't change the Activated Plugin's list selection. If you want to see what plug-ins were activated by a specific action:

  1. Select all the items in the list (Ctrl+A).
  2. Perform the action that you expect to activate one or more plug-ins.
  3. Select the Refresh button to update the list.

The unselected items will be the newly activated plug-ins; the selected ones are those that were already active before the action. Alternatively, you can note the last plug-in loaded by number in the Order column, perform the action, then resort the Order column to see what plug-ins appear after the previously last plug-in.

Notice the trailing asterisks in the plug-in names. These are plug-ins that were loaded during the activation of the plug-in that is responsible for launching Eclipse, the plug-in known as the application plug-in. This plug-in contributes a class that implements the IPlatformRunnable interface to the org.eclipse.core.runtime.applications extension point. By default, the Workbench UI plug-in contributes an implementation of this interface that creates the workbench window, collects action contributions to the main menu bar, toolbar, and so on, and generally prepares the Eclipse workbench user interface for business.

The actual elapsed clock time will be greater than the sum of the Startup time column shown in the Activated Plugins view. This is because the latter doesn't include JVM activity prior to the loading of the Platform Runtime or CPU activity outside of plug-in startup. In the case shown in Figure 2, the start time was actually around 13 seconds from the time the launch configuration started the instance of the Run-time Workbench. It also includes some overhead that the development-time launch configuration itself introduces for tasks like building the plug-in list.

Even with this overhead, the startup time looks pretty good, right?

Consequences of the Workbench's startup extension point

Let's update the list of active plug-ins by pressing the Refresh button. Voilà! Our first surprise is shown in Figure 3.


Figure 3. Plug-ins activated by the org.eclipse.ui.startup extension point
Plug-ins activated by org.eclipse.ui.startup after the workbench window opened

The selected plug-ins are those that were initially activated. What are these additional 11 plug-ins? Perhaps some were loaded because of the Runtime Spy perspective. More interestingly, there are several Studio plug-ins that look suspicious in Figure 3. Shown at the top of the list are "cheatsheet" and "internet". What are they and why are they loaded now? Going back to the user interface, we find choices related to the first plug-in under the Help pull-down menu, as shown in Figure 4.


Figure 4. Plug-in activated by org.eclipse.ui.startup that could be avoided?
Cheat sheets

It is likely that only new users would choose the Cheat Sheets menu options, so why are we paying the cost of loading their associated plug-in at startup? The Workbench > Startup preference page reveals the answer, as shown in Figure 5.


Figure 5. Plug-ins contributing to the org.eclipse.ui.startup extension point
Workbench startup preferences

The org.eclipse.ui.startup extension point was perhaps one of the more contentiously debated APIs for version 2.0. It is a carte blanche request to the Workbench UI to activate a plug-in once the workbench window is opened, bypassing the deferred load strategy. If a plug-in's manifest defines this extension point, then its plug-in class must implement the IStartup.earlyStartup method.

There are legitimate uses of this API. The length of this article doesn't allow for treatment of every item in this list. So let's consider the validity of a couple of the extenders shown above in Figure 5:

  • Cheat Sheets. The cheat sheet menu choices are built dynamically based on the installed features and reordered after each selection. There is no Workbench UI means to implement this behavior via extensions. It looks like this plug-in has no other choice but continue to "cheat."
  • Internet Preferences. This startup code initializes the Window > Preferences > Internet settings based on the system properties of the URL class. Since there is no way to know when this class will be referenced and since it has no explicit initialization methods, this appears legitimate. It may be prudent, however, to consider using a library extension. We'll return to why in a moment.

You may be wondering why the Workbench defines a Startup preference page in the first place. Deselecting one of the listed plug-ins gives the user the choice of having a faster startup with reduced functionality. For example, experienced developers with no need of the hints provided by the Cheat Sheets cascade menu could choose to disable its contribution to the org.eclipse.ui.startup extension point, thus removing the Help > Cheat Sheets menu option. Keep this in mind if your own plug-in contributes to this extension point. That is, code your plug-in defensively under the assumption that the plug-in class' IStartup.earlyStartup method may not have been called.

Returning to our example in Figure 3, consider the non-asterisk plug-in com.ibm.etools.internet in the list. Its stack trace in Figure 6 confirms why this plug-in was activated after the workbench window opened.


Figure 6. Workbench startup processing
Workbench startup processing

The Workbench's run method is highlighted, where the contributions to the org.eclipse.ui.startup extension point are processed. Subsequent plug-in activations at this point are all attributed to either the startup extension point or references thereof.


Sorting through potential WebSphere Studio hotspots

To see something Studio specific, let's open the J2EE perspective. (If you want to diagnose an easier scenario, open a single view, for example, Window > Show View > DB Servers, not its corresponding perspective; the list of activated plug-ins should be much shorter.) After opening the J2EE perspective, return to the Runtime Spy and select the Activated Plugin's Refresh button. Wow! The list jumps from 22 to 73 plug-ins, adding 20 seconds in plug-in activation (the prior total was just over three seconds). Figure 7 shows them sorted in plug-in activation order, with the most recently activated plug-in shown at the top.


Figure 7. Activated plug-ins after opening the J2EE perspective
Activated plug-ins after opening the J2EE perspective

In all fairness, the Runtime Spy adds overhead, especially if stack traces are captured, so true uninstrumented elapsed time is closer to 37 seconds overall from a warm start. But let's see if anything beyond the startup plug-ins jumps out as potentially unnecessary. To save space, the list below isn't exhaustive, since we accept that base components like EMF, JDT, and J2EE UI are required. But what about these?

  1. com.ibm.etools.validation.* (could be deferred or made optional?)
  2. com.ibm.etools.rsc.core.ui (db)
  3. com.ibm.etools.rdblib (db)
  4. com.ibm.etools.sqlmodel.* (db)
  5. com.ibm.sed.preferences (could be deferred?)
  6. com.ibm.etools.rsc (db)
  7. com.ibm.etools.sqlparse (db)
  8. com.ibm.etools.rdbschemagen.ui (db)
  9. com.ibm.etools.rdbexport.ui (db)
  10. com.ibm.etools.sqlbuilder (db)
  11. com.ibm.etools.subuilder (db and takes 1828ms to load!)
  12. com.ibm.etools.sqlj (db)

No views or editors specifically related to databases have been opened yet. So why were the relational database schema center (6) and so many other database-related plug-ins activated? The parenthetical comment "could be deferred" denotes those capabilities for which Eclipse has architected solutions to avoid activation until needed, as is especially evident in the case of preferences. Nonetheless, even when considered collectively, most of these are small potatoes. There are, however, some plug-ins that consume a lot of startup time and, as we'll see, their costs are tied to plug-in activation during the processing of extension points. The next section explains this cost more fully as it explores how startup costs are initially incurred. Then we'll return to our analysis of the J2EE perspective startup.

Understanding the relationship between plug-in activation and extension point processing

Saving some startup time by avoiding the activation of the subuilder plug-in (Stored Procedure and UDF Builder, according to its plug-in manifest) looks promising since it required almost 10% of the total time. Moreover, it is near the end of the activation sequence (72 of 73), so it may be easier to "trim off" than avoiding the activation of an earlier plug-in. The stack trace of this plug-in's activation is shown in Figure 8.


Figure 8. Plug-in activation stack trace for com.ibm.etools.subuilder
subuilder stack trace

There is no need for Studio's source code to understand what's happening; the stack trace alone points to the cause. The Eclipse class PartPane manages tabbed views like those you see containing the J2EE Hierarchy, Package Explorer, and Navigator views. As shown in Figure 8 beneath the text selection, the tabbed view PartPane is attempting to create an instance of the view associated with the J2EE Hierarchy tab, a class named J2EEView. Looking further up the stack, we see this class is in turn calling a helper that then calls the createExecutableExtension method.

The IConfigurationElement.createExecutableExtension method merits special attention. As you'll discover when debugging your own performance problems, this method instigates many of the plug-in activation cases that the Runtime Spy uncovers. To better understand what it does and how it affects plug-in activation, consider the simple extension point contribution shown in Listing 1. You may recognize this as the same listing, the canonical "Hello Eclipse" sample, from Part 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>
			

Note the processing of the class attribute of the <action> tag. This specifies the name of the class that will handle the menu choice selection, a class that must implement the IWorkbenchWindowActionDelegate interface. This class isn't located in the same plug-in as the one that processes the org.eclipse.ui.actionSets extension point, the Workbench UI plug-in, or any of its prerequisite plug-ins. So how does the Workbench UI plug-in create an instance of this class when it doesn't appear to lie on the plug-in's classpath?

It is the responsibility of a plug-in's classloader to resolve references to classes within its libraries. The classloader maps plug-in references to their corresponding JAR files containing the plug-in's classes, as in our example, SampleAction. Therefore, the Workbench UI plug-in doesn't have to "know" about the classes referenced by attributes like class of the <action> tag. Rather, it is the "Hello Eclipse" plug-in defining a dependency on the Workbench UI plug-in that allows it to access the plug-in class of the target plug-in and thereby have access to Hello Eclipse's classes via the target plug-in's classloader. To restate it more concisely, when Eclipse is unable to find a class, it asks the target plug-in's class loader to load the class; that's what the createExecutableExtension method does.

Avoiding premature plug-in activation linked to extension point processing

Returning to the stack trace shown in Figure 8, we recognize that the code near the middle of the text selection is processing extension contributions by calling createExecutableExtension -- and bingo! -- plug-ins start loading. Our quest turns to answering the burning questions: Was it necessary at this point? Can it be deferred until later?

Practically all classes that provoke the activation of another plug-in can ultimately be traced back to an invocation of the createExecutableExtension method. The invocation parameters specified on these calls denote the name of the attribute (often "class") and its value, the fully-qualified name of the class to be loaded. This leads back to the plug-in extension contribution responsible for the activation, in our case, the subuilder plug-in. An extract of its manifest is shown in Listing 2.


Listing 2. Subuilder plugin.xml extract
			
  <extension point = "com.ibm.etools.rsc.sp">
    <sp 
      id = "com.ibm.etools.subuilder.sp.NewSQLSPAction" 
      name="%STR_NEWWIZARD_SQLSP" 
      group ="SPFolderAction.New" 
      view = "datadef" 
      class="com.ibm.etools.subuilder.actions.create.NewSQLSPAction"/>
  </extension>
			

It terms of parameters, this extension contribution looks similar to the org.eclipse.ui.popupmenu extension point for defining menu choice contributions; that is, it defines a label (attribute "name"), placement (attribute "group"), target (attribute "view"), and most notably, a handler (attribute "class"). What differentiates the Eclipse extension and this particular implementation is that Eclipse's extension creates a delegate class to act as a proxy for the menu choice. It isn't until the menu choice is actually selected that the corresponding handler class is created, thereby deferring the activation of the plug-in containing the handler class. This same proxy strategy was applied to Studio's case above and the J2EE perspective opened almost seven seconds faster. The cost of creating the NewSQLSPAction instance and activating the plug-ins containing its referenced classes wasn't eliminated but rather changed to pay-as-you-go.


Conclusion

Now you see why this article is subtitled "Winning the shell game." It's all about managing the user's expectations and keeping their eyes away from what you hope they won't notice. In this particular case study example, the startup is now faster but the user will pay the same CPU costs later if they activate the database tools. That's acceptable since it is in small chunks, and more importantly, it moves the delay closer to the associated action where the user expects to pay.

Recall that the goal is defer code execution where possible, not only because it may result in a perceived improvement in performance, but also because the easiest code to optimize for speed is code that never executes. Eclipse's plug-in architecture makes it easier for you to create extensions that accomplish this, and the Runtime Spy helps you find those cases where your implementation could be improved.


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 developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

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

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

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

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers