简体   繁体   English

如何解决swing监听器内存泄漏?

[英]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). 所以我读到,Swing应用程序中的内存泄漏通常源于各种侦听器(鼠标,键,焦点等)的使用。 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 . 我发现处理问题的一种方法是使用WeakReference,可以在这里找到关于swing侦听器的方法的完整细节。

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 ie 然后,我开始对NetBeans表单编辑器如何在监听器添加到表单后生成代码进行清理并发现NetBeans通过包装对象注册侦听器(即

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 . 但是生成的代码似乎没有通过调用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? 在处理侦听器时,您是否有其他方法确保在完成侦听后始终收集垃圾?

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. 所以底线是NetBeans没有做任何导致内存“泄漏”的事情,因为组件被框架引用而不是它的外部,组件引用匿名类,而匿名类又参考框架 - 处理框架并且整个图表都无法访问,但您必须小心听众,因为他们可以对您这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM