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

时间:2009-12-10 01:31:41

标签: java swing memory-leaks listeners

背景

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

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

我发现处理问题的一种方法是使用WeakReference,可以找到关于使用swing侦听器的方法的详细信息here

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

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

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

问题

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

在处理侦听器时,您是否有其他方法可以确保在完成侦听器时始终对它们进行垃圾回收?

1 个答案:

答案 0 :(得分:14)

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

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

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

所以最重要的是NetBeans没有做任何导致内存“泄漏”的事情,因为组件被框架引用而不是在框架之外,组件引用匿名类,而匿名类又引用框架 - 处理框架并且整个图形无法访问,但您必须小心听众,因为他们可以对您执行此操作。