They have a quick big heavy-duty Eclipse RCP app running in their call centre, where a minute downtime can cause thousands of Rands (hmm, that would be thousands of Euros/Dollars as well) financial losses.
Needless to say, this only happens on Windows. Windows limits the number of what they term "GDI handles". These are basically OS handles to graphical objects, like images, fonts, colours, cursors, and GC (as in Graphical Context, not garbage collection)
For more background on this GDI handle problem, read this article.
The important here is: in SWT you as developer MUST dispose all graphical objects yourself, just like working with e.g. file IO or database connections.
In the normal way of working, you would e.g. create a RCP ViewPart, add widgets to it, and then eventually it is closed, and RCP dispose it and all the widgets on it. So for the typical widget, dialog or viewpart you are covered.
However, when you start to instantiate your own Font, Color, Image, GC or Cursor, you need to keep track manually, and call dispose() on the instances.
The best way is to make use of ImageRegistry, FontRegistry and ColorRegistry (look at JFaceResources class for the default registry instances).
In real life, though, we have two big culprits:
1) Developers like to create custom widgets (and yes, sometimes we actually need it as well). This typically entails using a number of these graphics classes, especially the GC class.
A lot of developers then forget to call dispose() on the GC object after it has been used.
2) I find that a lot of people using Eclipse RCP or SWT does not know that they need to dispose these graphics objects, and they also do not use the registry classes. Or they might think they must only do it with Images, Colors and Fonts, and then they creating new Cursor and GC instances all over without disposing it.
It takes only a few of these leaked instances to crash an application over time.
How do I solve it?
I have tried different tools, but found the best tool for me is Sleak.
Basically, you get the Sleak plugin, make it part of your runtime plugins, and then you need to change your perspectives to include the Sleak View as well.
You can get a good tutorial on using it here.
Sleak can take a snapshot of the existing GDI handles that are open, with the option to give you a stacktrace so you can see where each one is created. Then you can open a screen, or perform some actions, and get a difference, which will indicate whether any new handles has been created form the previous snapshop.
Now all you need is some patience, as you'll have to try out various functionality of your application, and find those handles that does not get disposed.
I've sent some fixes to my client, and now only time will tell if I got all those leaks...
[Update 31-5-2010] I have found another tool that I want to play with that will help find these kind of leaks, as well as debug UI layouts: Yari.

0 comments:
Post a Comment