0

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

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

内容取自一个 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 的内存。

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

4

1 回答 1

3

几个原因:

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

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

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

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

于 2012-07-08T17:20:31.803 回答