【问题标题】:How to resolve swing listener memory leaks?如何解决摇摆监听器内存泄漏?
【发布时间】:2010-12-25 02:07:36
【问题描述】:

背景

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

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

我发现处理该问题的一种方法是使用 Wea​​kReference,有关摇摆侦听器方法的完整详细信息可以在 here 找到。

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

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

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

问题

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

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

【问题讨论】:

    标签: java swing memory-leaks listeners


    【解决方案1】:

    首先更正一下,这里的潜在泄漏并不小。匿名内部类持有对外部类的引用,因此只要侦听器可访问,它就会持有整个类。

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

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

    所以底线是 NetBeans 没有做任何事情来导致内存“泄漏”,因为组件是由框架引用的,而不是在框架之外,并且组件引用了匿名类,而匿名类又引用了框架 -处置框架并且整个图表无法访问,但您必须小心听众,因为他们可以对您这样做。

    【讨论】:

    • 非常清楚 Yishai,您在处理内存泄漏严重的花哨应用程序中的侦听器时采取了什么方法?
    • @Clinton,一旦我诊断出问题(这需要一段时间,进行大量分析),我肯定会在窗口处置时取消注册侦听器。我不记得所有细节,但这是关键 - 我当时不知道弱引用作为问题的标准解决方案,我可能已经能够使用它。
    • @Yishai 我一直在做注销,因为听众正在离开范围......但它似乎有点笨拙,并开始寻找更好的解决方案。再次感谢您的更正。
    • 我现在的软件做了你曾经做过的事=\
    猜你喜欢
    • 2018-05-03
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 2013-04-09
    • 1970-01-01
    相关资源
    最近更新 更多