java - 垃圾收集器在java中不起作用?

标签 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 内存中删除所有 BufferedImage?没有对这些 BufferedImages 的引用,我说得对吗?

最佳答案

我同意durron597的观点,这个问题确实已经有答案了。 而且,正如他还所说,您不能为程序提供比完成屏幕捕获、处理和列表清除循环所需的内存更少的内存。

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

您的程序将在某个时刻稳定其内存使用情况,并且很可能会永远运行。事实上,我确实尝试过(但不是永远)。

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

JVM

这是之后使用的内存量:

Memory Usage

它运行了 6 个小时(几乎拍摄了 70 万张屏幕截图!):

Running Time

因此,如果您确实需要,您仍然可以限制其内存使用 - 但必须这样做吗?

来自javadocs : “调用 gc 方法表明 Java 虚拟机会努力回收未使用的对象,以使它们当前占用的内存可供快速重用。”

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

关于java - 垃圾收集器在java中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31598086/

相关文章:

java - MySQL/Java : Incorrect date value: '1990' for column

java - 从构造函数返回 ArrayList 的集合

java - 将变量传递给方法以添加到通用数组列表 - Java

Android位图回收

java - 如何在android中使用JavaCv的cvSaveImage

java - 自动完成 Struts2 jQuery

java - 如何使用java中的swing在屏幕键盘上显示打字导师?哪种布局效果最好?

java - 发出 GET 请求以生成数独

c# - 为什么 GC 似乎在递归函数中失败?

python - 列表中的最后一个对象在删除后不会被删除。什么时候有效删除?