参考Factors Affecting Garbage Collection Performancejava - Does GC release back memory to OS? - Stack Overflow

Java 的垃圾回收器(GC)在某些情况下会将内存释放回操作系统,但这并不是普遍的、在所有场景下都会发生的行为。

1. 不同的垃圾回收器实现和策略

  • 部分回收器会释放

  • 例如,某些 Java 版本中的 G1 垃圾回收器在满足一定条件时,会尝试将未使用的内存归还给操作系统。它会根据自身的算法和策略,判断内存的使用情况,如果发现有连续的、较大的空闲内存区域,并且认为这些内存在短期内不太可能被再次使用,就可能会将其释放回操作系统。

  • 部分回收器不会释放

  • 像 Serial 收集器和 Parallel 收集器等一些传统的垃圾回收器,通常不会主动将内存释放回操作系统。它们主要关注的是在 Java 虚拟机内部对内存的管理和回收,以满足 Java 程序的内存需求。这些回收器在回收内存后,会将空闲内存保留在 Java 虚拟机的内存池中,以便后续 Java 程序的对象分配使用。

2. 影响内存释放的因素

  • 内存碎片化

  • 如果 Java 堆内存存在严重的碎片化,即使经过垃圾回收后有一些空闲的内存空间,但这些空间可能是不连续的,难以满足操作系统对内存回收的要求(通常要求连续的内存块),那么垃圾回收器就不太可能将这些内存释放回操作系统。

  • 内存使用模式

  • 如果 Java 程序的内存使用模式是频繁地创建和销毁对象,导致垃圾回收频繁发生,但每次回收后又很快会有新的对象分配需求,垃圾回收器可能会选择保留内存在虚拟机内部,而不释放回操作系统,以提高内存分配的效率。

3. 相关的配置参数

  • Java 虚拟机提供了一些配置参数来影响垃圾回收器的行为,以控制是否以及如何将内存释放回操作系统。

  • 例如,-XX:+UseG1GC -XX:G1HeapWastePercent等参数可以用于调整 G1 垃圾回收器的行为,使其更倾向于或者更不利于将内存释放回操作系统。通过调整这些参数,可以根据具体的应用场景和需求,优化 Java 程序的内存管理和垃圾回收性能。

  • JVM 提供了-XX:MinHeapFreeRatio-XX:MaxHeapFreeRatio 两个参数,用于配置这个归还策略。

  • MinHeapFreeRatio 代表当空闲区域大小下降到该值时,会进行扩容,扩容的上限为 Xmx

  • MaxHeapFreeRatio 代表当空闲区域超过该值时,会进行“缩容”,缩容的下限为Xms

4. 不同版本JDK的归还内存机制

JAVA 版本

垃圾回收器

VM Options

是否可以“归还”

JAVA 8

UseParallelGC(ParallerGC + ParallerOld)

-Xms100M -Xmx2G -XX:MaxHeapFreeRatio=40

JAVA 8

CMS+ParNew

-Xms100M -Xmx2G -XX:MaxHeapFreeRatio=40 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

JAVA 8

UseG1GC(G1)

-Xms100M -Xmx2G -XX:MaxHeapFreeRatio=40 -XX:+UseG1GC

JAVA 11

UseG1GC(G1)

-Xms100M -Xmx2G -XX:MaxHeapFreeRatio=40

JAVA 16

UseZGC(ZGC)

-Xms100M -Xmx2G -XX:MaxHeapFreeRatio=40 -XX:+UseZGC