Java: 调用 GC 占用所有空闲内存

Java: calling to GC takes all free memory

IDE:IntelliJ,JDK16.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() 的文档:

Returns the amount of free memory in the Java Virtual Machine.

并与 totalMemory() 比较:

Returns the total amount of memory in the Java virtual machine. The value returned by this method may vary over time, depending on the host environment.

所以,将您的程序更改为

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