JTextArea.setText(null);不释放内存
我使用的是Swing,我有一个包含几个JPanel的JFrame,其中一个JTextArea。JTextArea.setText(null);不释放内存
当用户点击某个菜单时,设置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(免费())。
因此,当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 +ž仍然工作,让您恢复以前的(30 MB)内容是什么?你的想法...
如果这些都不是正确的,使用内存分析器像Eclipse MAT找出拥有这个庞大对象的引用(你会发现char[]
60 MB的大小)。
GC可能不会立即采取行动。你是否在任何地方保留对大字符串的其他引用? – Tudor 2012-07-08 17:16:52
请测试JTextArea.getDocument(JTextComponent的模型),然后确定其getLength() – mKorbel 2012-07-08 17:18:54
我没有任何其他引用大字符串任何地方......他们只在该函数。我会测试你的建议。 – HBv6 2012-07-08 17:33:55