gpt4 book ai didi

java - 空闲的简单 Java Swing 应用程序内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:29:56 25 4
gpt4 key购买 nike

我目前正在调查我们的一个应用程序中的内存泄漏。经过进一步调查,我想出了两个简单的 java swing 应用程序的测试,它们闲置了将近 14 个小时。这两个应用程序都包含 30 个 JButton。

第一个应用程序正在为其 Action 监听器使用强引用:

jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

第二个应用程序正在为其 Action 监听器使用弱引用:

jButton1.addActionListener(new WeakActionListener(new MyActionListener(), this.jButton1))

这是 WeakActionListener 的实现:

public class WeakActionListener implements ActionListener {

private WeakReference weakListenerReference;
private Object source;


public WeakActionListener(ActionListener listener, Object source) {
this.weakListenerReference = new WeakReference(listener);
this.source = source;
}

public void actionPerformed(ActionEvent actionEvent) {
ActionListener actionListener = (ActionListener) this.weakListenerReference.get();
if(actionListener == null) {
this.removeListener();
} else {
actionListener.actionPerformed(actionEvent);
}
}

private void removeListener() {
try {
Method method = source.getClass().getMethod("removeActionListener", new Class[] {ActionListener.class});
method.invoke(source, new Object[] {this});
} catch(Exception ex) {
ex.printStackTrace();
}
}

}

我使用 JConsole 分析了这两个应用程序 14 个小时。我只是让他们在那个时间段内闲置。它表明,无论是使用弱引用还是使用强引用,这两个应用程序的内存堆消耗都会随着时间的推移而增加。

我的问题是,这是 Java Swing API 中的错误吗?解决这种内存泄漏的其他方法是什么?

提前致谢!

最佳答案

JDK实际上包含很多内存泄漏,但是您描述的情况不是其中之一。内存消耗很大,因为即使应用程序处于空闲状态,操作系统也不会 - 它有时会向应用程序发送输入事件。处理这些事件需要一些内存分配,因此您会看到一个不断增长的堆。而且它可能不会被收集,因为它不需要 - 应用程序在堆中有足够的空闲内存,所以它不会过于频繁地进行 GC。

此外,您在 Java 中使用了错误的内存泄漏分析方法。正确的应该是:

  1. 您使用要分析内存泄漏的功能创建可能的简单应用程序。
  2. 您执行了您认为内存应该为 GC 做好准备的所有步骤。对于与 GUI 相关的应用程序,我建议添加对 ((SunToolkit)Toolkit.getDefaultToolkit()).realSync() 的调用处理所有异步调用和事件。这是一个内部 API,因此它不应该在真正的应用程序上使用,但它对此类实验性应用程序非常有用。
  3. 之后您尝试分配一些大对象以导致 OutOfMemoryError。您可以确定在抛出 OOME 之前,Java 将收集所有空闲对象。在 OOME 的 catch block 中,您只需使用 System.exit(0); 退出应用程序。

现在是最有趣的部分:您应该使用 -Xmx20M 运行应用程序为堆和 -Xrunhprof:format=b,file=<Path to output file> 设置低内存量.因此,当应用程序完成时,您可以确定所有空闲对象都会因为您造成的 OutOfMemory 而被 GC 处理,并且 hprof 将转储所有剩余对象的堆。您可以使用一种可用的工具(如 jhat)或 eclipse 中的一些工具来分析堆。

关于java - 空闲的简单 Java Swing 应用程序内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15627939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com