Finding SWT Leaks with Sleak

Finding SWT Leaks with Sleak

In SWT, the mantra is “if you created it, you dispose it.”

The problem is, people forget to dispose which makes leaks a reality.

For example, ever come across this dreaded exception from SWT?
[code lang=”java”]

org.eclipse.swt.SWTError: No more handles
at org.eclipse.swt.SWT.error(SWT.java:2966)
at org.eclipse.swt.SWT.error(SWT.java:2863)
at org.eclipse.swt.SWT.error(SWT.java:2834)
at org.eclipse.swt.widgets.Widget.error(Widget.java:395)
at org.eclipse.swt.widgets.Control.createHandle(Control.java:482)
at org.eclipse.swt.widgets.Composite.createHandle(Composite.java:229)
at org.eclipse.swt.widgets.Control.createWidget(Control.java:497)
at org.eclipse.swt.widgets.Scrollable.createWidget(Scrollable.java:131)
at org.eclipse.swt.widgets.Control. (Control.java:97)
at org.eclipse.swt.widgets.Scrollable. (Scrollable.java:72)
at org.eclipse.swt.widgets.Composite. (Composite.java:87)

[/code]

One of the most common causes of this type of exception is a resource leak. In SWT, you’re allocating operating system resources for widgets, images, fonts, and other graphical objects. Since there is a platform-specific limit on the amount of resources you can allocate, you must be careful to free any objects that you allocate. To see what resources your application has allocated, the SWT team has a tool called Sleak. To get an idea of how Sleak works, let’s modify the famous RCP Mail example. The first step will be to add the Sleak view to the RCP Mail perspective (Perspective.java):
[code lang=”java”]
layout.addStandaloneView(NavigationView.ID, false, IPageLayout.LEFT, 0.25f, editorArea);
IFolderLayout folder = layout.createFolder(“messages”, IPageLayout.TOP, 0.5f, editorArea);
folder.addPlaceholder(View.ID + “:*”);
folder.addView(View.ID);
folder.addView(“org.eclipse.swt.sleak.views.SleakView”); // add sleak here!
[/code]

The next step is to simulate a leak so we can show the benefit of using Sleak. We can simulate a resource leak by creating a bold font and never disposing of it in the RCP Mail view (View.java):
[code lang=”java”]

// setup bold font
// comment out the safe way of getting a bold font via the jface registry
// Font boldFont = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
FontData[] fontData = JFaceResources.getDialogFont().getFontData();
for (int i = 0; i < fontData.length; i++) { FontData data = fontData[i]; data.setStyle(SWT.BOLD); } boldFont = new Font(parent.getDisplay(), fontData); // this should be disposed in dispose() ... [/code] Ok, now that we have the code modifications out of the way, we need to launch our application. Note, in order to have Sleak function properly, you have to enable some options:
org.eclipse.ui/debug=true
org.eclipse.ui/trace/graphics=true

The easiest way to do this is in your Eclipse application launch configuration. There is a ‘Tracing’ tab that allows you to tweak options:
tracing

Once that is done, we can launch our application and find the ‘Sleak’ view:

sleak1

If you press the ‘Snap’ button in Sleak, it will take a snapshot of the current allocated resources. To demonstrate the leak, we need to open two more messages in the mail application, close both of them, and then go back to the Sleak view to press the ‘Diff’ button:

sleak3

Sleak now informs us that there are two more fonts allocated than before, we have found our leak! If you click the ‘Stack’ option, you can even get a stracktrace that tells you where the resource was allocated. A fix for this problem goes back to the SWT mantra of “if you created it, you dispose it.” In our view, we simply need to dispose of the bold font when we’re done using it (or use the font registry like before):
[code lang=”java”]

public void dispose() {
super.dispose();
boldFont.dispose(); // we need to dispose that font to prevent a leak!
}

[/code]

Here’s a zip of mail example with the leak if you want to toy with Sleak.

Hope this helps!

9 Comments
  • Adil
    Posted at 7:55 pm, April 17, 2009

    Hey,

    Can this be done on a rcp based on eclipse 3.3? We would definitely like to profile out mamoth RCP application for SWT leak. Bseides, how do i wrap the Sleak class in a view. Sorry, i am very new to RCP hence my dumb question.

    Thanks.

  • Dave Henderson
    Posted at 11:07 pm, April 17, 2009

    For those that are unaware, note also that many registry classes already exist in JFace (under org.eclipse.jface.resource), that will manage disposing of resources created through them automatically.

  • Posted at 1:21 am, April 21, 2009

    Thanks, Chris Aniszczyk ^^

  • Posted at 4:11 pm, November 6, 2009

    Hi,

    I’m trying to use Sleak on my RCP gmf-based application without success : I’m still having the popup menu with the message “Warning: Deviceis not tracking resource allocation”

    The only difference that I can see with your post is that simply set the o.e.swt.tools plugin and its required plugins in my launch configuration and open the view via Alt+shift+Q,Q

    Nota : I can use Sleak on my Eclipse use for the development.

    Do you know a common issue that can be possible?

    Thanks by advance

  • Posted at 5:02 pm, November 6, 2009

    Ok I found a way to do it working, guiding by this newsgroup thread.

  • Posted at 3:32 pm, March 2, 2010

    just to be up-to-date :
    the id of the Sleak view seems to have changed, now it is:
    org.eclipse.swt.tools.views.SleakView

  • eclipseRcpPrg
    Posted at 9:11 pm, August 6, 2010

    Hi I m trying to run the sleak on my GUI. I am getting the warning which says “Device is not tracking resource allocation”. I followed all the steps to implement sleak. i have to command line args needed for my GUI which I used to pass before and then I came to know that I need to give .options file path also in the arguments. I am doing that but still no use. I changed the run configuration/ tracing options also to enable debug and deguggraphics still I am getting the same warning … could you please let me know whatz wrong ? this is really critical for my project.

  • Rajeev
    Posted at 12:11 pm, November 28, 2011

    i am using Version
    Eclipse : 3.5.0
    Build id: I20090611-1540 and downloaded sleak plugin Sleak plug-in for Eclipse 3.4 M6 – 3.5. I have condifured my run option but still i am getting the error “Device is not tracking resource allocation”
    Plz help