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` 设置最大堆大小。对于这个小程序,两者都可以起到同样的效果。