Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve swing listener memory leaks?

Background

So I read that often memory leaks within Swing applications originate from the use of various listeners (mouse, key, focus, etc). Essentially, because you register an object as a listener and forget to deregister the object, the notifier ends up holding onto the reference of the object, and leaks a bit of memory.

I knew our application wasn't deregistering listeners and did a bit of research on potential solutions:

I found one approach in dealing with the problem was the use of a WeakReference, full details on the approach with swing listeners can be found here.

I then became curious about how the NetBeans form editor was generating code to clean up after listeners added to the form and discovered that NetBeans was registering listeners via a wrapping object i.e.

argTypeComboBox.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent evt) {
      argTypeComboBoxItemStateChanged(evt);
    }
});

But the generated code did not seem to ever clean up by calling removeItemListener.

Questions

Is the wrapping object acting like a weak reference? To me it looks like it could leak a tiny amount of memory (the size of the wrapping object)?

Do you have alternative approaches when dealing with listeners to ensure that they are always garbage collected when you are finished with them?

like image 849
Clinton Avatar asked Dec 10 '09 01:12

Clinton


1 Answers

First a correction, the potential leak here is not tiny. An anonymous inner class holds a reference to the outer class, so as long as the listener is reachable it will hold on to the whole class.

However, this is typically not a problem, as you are adding listeners to objects on a frame. When that frame is disposed (important that it be disposed, though) and has no more references (which is pretty typical), all of its components become unreachable (if you didn't do anything fancy) and the whole thing gets garbage collected.

I once dealt with an application, however, that did do fancy things, such as registering open windows with a different window, so if the window was closed, it was still registered - big time memory leak - these windows were not tiny.

So the bottom line is that NetBeans isn't doing anything to cause memory "leaks" here as the component is referenced by the frame and not outside of it and the component references the anonymous class, which in turn references the frame - dispose the frame and the whole graph is unreachable, but you do have to be careful with listeners, as they can do this to you.

like image 58
Yishai Avatar answered Oct 09 '22 12:10

Yishai