Java:调用GC会占用所有可用内存

IDE:IntelliJ、JDK 16.0.2

代码:

public static void main(String[] args) {
    Runtime runtime = Runtime.getRuntime();
    System.out.println("Free memory before gc: " + runtime.freeMemory() / (1024 * 1024) + " Mb");
    runtime.gc();
    System.out.println("Free memory after gc: " + runtime.freeMemory() / (1024 * 1024) + " Mb");
}

输出:

Free memory before gc: 251 Mb
Free memory after gc: 13 Mb

问题:为什么调用垃圾回收“吃掉”所有内存?

回答

请注意以下文档freeMemory()

返回Java 虚拟机中的可用内存量。

并比较totalMemory()

返回 Java 虚拟机中的总内存量。此方法返回的值可能会随时间变化,具体取决于宿主环境。

因此,将您的程序更改为

public static void main(String[] args) {
    Runtime runtime = Runtime.getRuntime();
    log("before gc", runtime);
    runtime.gc();
    log("after gc", runtime);
}

static void log(String point, Runtime runtime) {
    System.out.println("Free memory " + point + ": "
        + runtime.freeMemory()  / (1024 * 1024) + " MB of "
        + runtime.totalMemory() / (1024 * 1024) + " MB");
}

在我的机器上,它打印

Free memory before gc: 253 MB of 256 MB
Free memory after gc: 13 MB of 14 MB

表明垃圾收集不仅释放内存,而且还给操作系统。

默认配置旨在适应更大的应用程序,并且以如此低的内存使用率执行(完整)垃圾收集是相当不寻常的。因此,堆具有更大的初始大小并因强制垃圾收集而减少也就不足为奇了。

当我使用该-Xms14M选项运行相同的程序时,我得到

Free memory before gc: 12 MB of 14 MB
Free memory after gc: 13 MB of 14 MB

  • `-Xms` 设置初始堆大小,`-Xmx` 设置最大堆大小。对于这个小程序,两者都可以起到同样的效果。

以上是Java:调用GC会占用所有可用内存的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>