Now that the leak has been discovered, it needs to be fixed. The solution is to dispose()
the Color
once it is finished with, which will be when the view itself is removed.
A quick investigation of ClockWidget
suggests that overriding dispose()
might work. (Note that this is not the correct solution; see later for why.)
dispose()
method in ClockWidget
with the following code:@Override public void dispose() { if(color != null && !color.isDisposed()) color.dispose(); super.dispose(); }
There are 87 Color instances There are 91 Color instances There are 94 Color instances There are 98 Color instances
dispose()
method (since it doesn't work as intended) and modify the constructor of ClockWidget
to add an anonymous DisposeListener
that disposes of the associated Color
object:public ClockWidget(Composite parent, int style, RGB rgb) { super(parent, style); this.color = new Color(parent.getDisplay(),rgb); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { if(color != null && !color.isDisposed()) color.dispose(); } }); }
There are 87 Color instances There are 88 Color instances There are 88 Color instances There are 88 Color instances
The leak has been plugged.
Once the source of the leak has been identified, the correct course of action is to dispose()
the Color
object when no longer needed. However, although it is tempting to think that overriding the dispose()
method of ClockWidget
would be all that is needed, in fact it doesn't work. The only time dispose()
is called is at the top level Shell
(or ViewPart
), and if there are no registered listeners then the dispose method is not called on any components beneath. Since this can be quite counter-intuitive, it is of value to have stepped through code to verify that that is the behavior so that it can be avoided in the future.
Detecting, and resolving, resource leaks can be a time-consuming process. There is a plug-in, developed by the SWT team, which can perform a snapshot of resources and verify whether there are any leaks using a similar technique to the preceding one. The plug-in is located at the SWT tools update site (refer to http://www.eclipse.org/swt/tools.php and search for Sleak for more information) and can be installed to avoid having to modify code (as was done in this example) for the purposes of monitoring allocated resources.
Don't forget when performing tests that the first one or two runs may give different results by virtue of the fact that other resources may be being initialized at the time. Take a couple of readings first before relying on any data, and bear in mind that other plug-ins (that maybe executing in the background) may be doing resource allocation as well.
Finally, when working with any SWT widget, it is good practice to check whether the resource is already disposed or not. The JavaDoc for dispose()
says that this is not strictly necessary, and that resources which are already disposed will treat this as a no-op method.
Q1. Where do resource leaks come from?
Q2. What are the different types of Resources
?
Q3. How can you enable SWT resource tracking?
Q4. Once enabled, how do you find out what objects are tracked?
Q5. What's the right way and the wrong way to free resources after use?
Now that the ClockWidget
is running, try the following:
Font
object, with disposal.Resource
.setColor()
method which allows you to change the color.