【问题标题】:JTextArea.setText(null); does not free the memoryJTextArea.setText(null);不释放内存
【发布时间】:2012-07-08 06:15:37
【问题描述】:

我正在使用 Swing,我有一个包含几个 JPanel 的 JFrame,其中一个 JTextArea 内有一个 JTextArea。

当用户点击某个菜单时设置 JTextArea 内容(ActionListener.actionPerformed(populate()))。

内容取自一个 30MB 的文本文件:

private void populate () {
        StringBuilder strB = new StringBuilder();
        try {
            FileReader fr = new FileReader("file30mb.txt");
            BufferedReader br = new BufferedReader(fr);
            String strLine;

            while ((strLine = br.readLine()) != null) {
                strB.append(strLine).append(System.getProperty("line.separator"));
            }

            fr.close();
            br.close();
        } catch (IOException e) {
            System.err.println(e);
        }

        jTextArea1.setEditable(false);
        jTextArea1.setText(strB.toString());
        jTextArea1.setCaretPosition(0);
}

这个过程会占用大量内存,大约200MB。

还有另一个菜单,当用户点击它时,JTextArea 会被清除(基本上它会调用一个执行 jTextArea1.setText(null) 的方法)。该事件的处理方式与之前相同:ActionListener.actionPerformed(free())

因此,当 JTextArea 为空时,我希望内存使用量比以前低……但不幸的是,事实并非如此。如果我进入任务管理器,我会看到与之前相同的内存使用情况(大约 200MB),但 JTextArea 是空的!

我错过了什么?

编辑我也试过这个:

jTextArea1.setText(strB.toString());
jTextArea1.setText("");
Runtime r = Runtime.getRuntime();
r.gc();
System.out.println(jTextArea1.getDocument().getLength()); // prints "0"

但它仍然需要 200MB 的内存。

EDIT 2 如果我删除“GUI 部分”(我的意思是 jTextArea1.setText() 等),它仍然会占用大量内存。它应该占用“0 内存”,因为我没有在 JTextArea 中写入任何内容,但我只是读取了一个文本文件,然后什么也不做。我错了吗?

【问题讨论】:

  • GC 可能没有立即采取行动。您是否在任何地方保留对大字符串的任何其他引用?
  • 请测试JTextArea.getDocument(JTextComponent的模型),然后确定它的getLength()
  • 我没有在任何地方保留对大字符串的任何其他引用......它们只在那个函数中。我会测试你的建议。
  • @mKorbel 我试过了,它按预期返回“0”。
  • @Pierpaolo Bagnasco 基本上所有 IDE 都已实现或可访问 JProfiler、profile single part、main + 并尝试 JTextArea.read,有一些视图可以确定实际内存使用情况,包括类或方法名称包括 GC 曲线图,顺便说一句,就我而言,问题出在我预期的某个地方:-),

标签: java swing memory-leaks jtextarea


【解决方案1】:

几个原因:

  • 垃圾回收会定期运行,它不会立即释放内存

  • JVM 进程内存和堆内存使用是两个不同的东西。启用详细 GC 日志记录或使用 jconsole/jvisualvm 连接到您的应用程序并检查实际堆使用情况。手动运行 GC

  • Ctrl + Z 是否仍在工作,允许您恢复以前的 (30 MB) 内容?你明白了……

如果这些都不对,请使用像 Eclipse MAT 这样的内存分析器来找出对这个巨大对象的引用(你会发现 char[] 大小为 60 MB)。

【讨论】:

  • Ctrl + Z 不起作用。所以我尝试手动运行 GC,但它仍然需要 200MB 的内存。 (我编辑了我的第一篇文章)
  • @PierpaoloBagnasco:那么,问题出在哪里?
  • 感谢 jconsole/jvisualvm 的建议...我发现我完全错了。我将提交的内存与实际使用的堆内存混淆了。我也使用过这个库:sizeof.sourceforge.net 了解每个感兴趣对象的内存使用情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2011-06-30
  • 2016-09-14
  • 2015-08-19
  • 2012-05-15
  • 2018-01-26
  • 2011-09-30
相关资源
最近更新 更多