为什么 OpenJDK 11 Java 垃圾收集器*减少*此示例程序中的可用内存?
Why is OpenJDK 11 Java garbage collector *decreasing* free memory in this sample program?
当我使用 OpenJDK 11(Windows 10 上的 Zulu 发行版)编译和 运行 以下非常简单的 Java 程序时:
public class GCTest {
public static void main(String[] args) {
System.out.println("Free memory before garbage collection: " + Runtime.getRuntime().freeMemory());
Runtime.getRuntime().gc();
System.out.println("Free memory after garbage collection: " + Runtime.getRuntime().freeMemory());
}
}
看起来垃圾回收正在减少可用内存量:
Free memory before garbage collection: 266881496
Free memory after garbage collection: 7772200
当我 运行 使用 Oracle 的 Java 8 时,这不会发生:
Free memory before garbage collection: 254741016
Free memory after garbage collection: 255795064
这是为什么?
我认为您看到的是 JDK 决定您的堆对于您的应用程序的需求来说太大了,并将它的块返回给操作系统,从而减少了您的 Java 堆大小作为副作用还有 free/unused 堆内存。
答案是:Java 11 的 GC(当通过 System.gc()
显式调用时)可以减少 Java 进程(在 Java 中)的已用内存称为 totalMemory
)。
在 Java 8 中,默认的垃圾收集器无法减少 Java 进程的已用内存。 Java 进程占用的内存从未被释放。只有切换到 G1GC
垃圾收集器(选项 '-XX:+UseG1GC'
) Java 8 才能减少 Java 进程的已用内存(如果您手动调用 System.gc()
).
"free memory"是Java进程占用的内存,目前没有使用。因此,如果您执行垃圾收集并且 Java 占用的内存减少,则可用内存量也会减少。
因此,计算 Java 进程的 "free memory" 的常用方法是使用
Runtime r = Runtime.getRuntime();
long free = r.maxMemory() - r.totalMemory() + r.freeMemory();
这种方式与Java进程当前占用的内存无关
当我使用 OpenJDK 11(Windows 10 上的 Zulu 发行版)编译和 运行 以下非常简单的 Java 程序时:
public class GCTest {
public static void main(String[] args) {
System.out.println("Free memory before garbage collection: " + Runtime.getRuntime().freeMemory());
Runtime.getRuntime().gc();
System.out.println("Free memory after garbage collection: " + Runtime.getRuntime().freeMemory());
}
}
看起来垃圾回收正在减少可用内存量:
Free memory before garbage collection: 266881496
Free memory after garbage collection: 7772200
当我 运行 使用 Oracle 的 Java 8 时,这不会发生:
Free memory before garbage collection: 254741016
Free memory after garbage collection: 255795064
这是为什么?
我认为您看到的是 JDK 决定您的堆对于您的应用程序的需求来说太大了,并将它的块返回给操作系统,从而减少了您的 Java 堆大小作为副作用还有 free/unused 堆内存。
答案是:Java 11 的 GC(当通过 System.gc()
显式调用时)可以减少 Java 进程(在 Java 中)的已用内存称为 totalMemory
)。
在 Java 8 中,默认的垃圾收集器无法减少 Java 进程的已用内存。 Java 进程占用的内存从未被释放。只有切换到 G1GC
垃圾收集器(选项 '-XX:+UseG1GC'
) Java 8 才能减少 Java 进程的已用内存(如果您手动调用 System.gc()
).
"free memory"是Java进程占用的内存,目前没有使用。因此,如果您执行垃圾收集并且 Java 占用的内存减少,则可用内存量也会减少。
因此,计算 Java 进程的 "free memory" 的常用方法是使用
Runtime r = Runtime.getRuntime();
long free = r.maxMemory() - r.totalMemory() + r.freeMemory();
这种方式与Java进程当前占用的内存无关