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

Cli*_*ton 9 java swing memory-leaks listeners

背景

所以我读到,Swing应用程序中的内存泄漏通常源于各种侦听器(鼠标,键,焦点等)的使用.本质上,因为您将对象注册为侦听器而忘记取消注册该对象,通知程序最终会保留对象的引用,并泄漏一些内存.

我知道我们的应用程序并没有取消注册听众,并对潜在的解决方案进行了一些研究:

我发现处理问题的一种方法是使用WeakReference,可以在这里找到关于swing侦听器的方法的完整细节.

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

argTypeComboBox.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent evt) {
      argTypeComboBoxItemStateChanged(evt);
    }
});
Run Code Online (Sandbox Code Playgroud)

但生成的代码似乎并没有通过调用来清理removeItemListener.

问题

包装对象是否像弱引用一样?对我来说,它看起来可能会泄漏少量内存(包装对象的大小)?

在处理侦听器时,您是否有其他方法确保在完成侦听后始终收集垃圾?

Yis*_*hai 14

首先是修正,这里潜在的泄漏并不是很小.匿名内部类包含对外部类的引用,因此只要侦听器可访问,它就会保留整个类.

但是,这通常不是问题,因为您要将侦听器添加到帧上的对象.当这个框架被丢弃时(重要的是它被丢弃)并且没有更多的引用(这是非常典型的),它的所有组件都变得无法访问(如果你没有做任何花哨的事情)并且整个事情被垃圾收集.

我曾经处理过一个应用程序,但确实做了很多花哨的事情,例如用不同的窗口注册打开的窗口,所以如果窗口关闭,它仍然被注册 - 大时间内存泄漏 - 这些窗口并不小.

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