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

zzf*_*ima 1 java garbage-collection

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");
}
Run Code Online (Sandbox Code Playgroud)

输出:

Free memory before gc: 251 Mb
Free memory after gc: 13 Mb
Run Code Online (Sandbox Code Playgroud)

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

Hol*_*ger 6

请注意以下文档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");
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上,它打印

Free memory before gc: 253 MB of 256 MB
Free memory after gc: 13 MB of 14 MB
Run Code Online (Sandbox Code Playgroud)

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

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

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

Free memory before gc: 12 MB of 14 MB
Free memory after gc: 13 MB of 14 MB
Run Code Online (Sandbox Code Playgroud)

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