我有一个非常简单的程序,可以将截图保存到ArrayList - 例如我拍摄100个截图,将它们添加到列表中,然后清除列表。像这样:
public static void main(String[] args) {
JFrame frame = new JFrame(); // creating simple JFrame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
List<BufferedImage> list = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
BufferedImage capture = makeScreenShot();
list.add(capture);
System.out.println("capture saved to arraylist " + i);
}
list.clear();
}
和方法makeScreenShot:
private static BufferedImage makeScreenShot() {
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
Toolkit toolkit = Toolkit.getDefaultToolkit();
Rectangle screenBounds = new Rectangle(toolkit.getScreenSize());
BufferedImage capture = robot.createScreenCapture(screenBounds);
return capture;
}
如果我运行这个简单的程序,我的任务管理器(Windows)显示该程序使用大约1GB的RAM。为什么Java垃圾收集器不能从RAM内存中删除所有BufferedImages?没有对这些BufferedImages的引用,我是对吗?
答案 0 :(得分:1)
我同意durron597,这个问题确实有答案。 而且,正如他所说,你不能给程序提供比完成屏幕截取,处理和清单清理所需的内存更少的内存。
如accepted answer中所述, JVM将尽可能多地使用内存,这没关系。
您的程序将在某个时刻稳定其内存使用量,并且很可能永远运行。我确实尝试过(实际上并非如此)。
但是我喜欢测试的较低堆大小版本 - 这就是我设置它的方式:
这是它之后使用的内存量:
它已经运行了6个小时(拍摄了近700k的截图!):
所以,如果你真的需要,你仍然可以限制其内存使用量 - 但是你必须这样做吗?
来自javadocs: “调用gc方法表明Java虚拟机花费了很多精力来回收未使用的对象,以便使它们当前占用的内存可用于快速重用。”
因此,System.gc()
只是一个建议 - 可能是really bad one。