垃圾收集器不在java中工作?

时间:2015-07-23 21:09:36

标签: java arraylist garbage-collection bufferedimage

我有一个非常简单的程序,可以将截图保存到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的引用,我是对吗?

1 个答案:

答案 0 :(得分:1)

我同意durron597,这个问题确实有答案。 而且,正如他所说,你不能给程序提供比完成屏幕截取,处理和清单清理所需的内存更少的内存。

accepted answer中所述, JVM将尽可能多地使用内存,这没关系

您的程序将在某个时刻稳定其内存使用量,并且很可能永远运行。我确实尝试过(实际上并非如此)。

但是我喜欢测试的较低堆大小版本 - 这就是我设置它的方式:

JVM

这是它之后使用的内存量:

Memory Usage

它已经运行了6个小时(拍摄了近700k的截图!):

Running Time

所以,如果你真的需要,你仍然可以限制其内存使用量 - 但是你必须这样做吗?

来自javadocs“调用gc方法表明Java虚拟机花费了很多精力来回收未使用的对象,以便使它们当前占用的内存可用于快速重用。”

因此,System.gc()只是一个建议 - 可能是really bad one