我正在使用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中写任何东西,但是我只是读取了一个文本文件,然后什么也不做。我错了吗?

最佳答案

几个原因:


垃圾收集定期运行,不会立即释放内存
JVM进程内存和堆内存的使用是两个不同的东西。启用详细的GC日志记录或使用jconsole / jvisualvm连接到您的应用程序,并检查实际堆使用情况。手动运行GC
Ctrl + Z仍在工作,可以还原以前的(30 MB)内容吗?你明白了...


如果所有这些都不对,请使用Eclipse MAT之类的内存探查器来找出对这个巨大对象的引用(您会发现60 MB的char[])。

关于java - JTextArea.setText(null);不释放内存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11385045/

10-09 20:02
查看更多