GC是否将内存释放回操作系统?

当垃圾收集器运行并释放内存时,此内存会返回到操作系统,或者它是否作为进程的一部分保留。 我的印象是,内存从未实际发布回操作系统,而是作为内存区/池的一部分保留,以便由同一进程重用。

结果,进程的实际内存永远不会减少。 一篇提醒我的文章是这个,Java的Runtime是用C / C ++编写的,所以我想同样的事情也适用?

更新
我的问题是关于Java。 我提到C / C ++,因为我假设Java的分配/释放是由JRE使用某种forms的malloc / delete完成的

HotSpot JVM确实将内存释放回操作系统,但不情愿地这样做,因为调整堆的大小是昂贵的,并且假设如果你需要那个堆,一旦你需要它再次。

您可以通过设置-XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30来使其更具攻击性,这将允许它在收集和约束已分配但未使用的堆内存量后花费更多的CPU时间GC循环。

假设您正在使用并发收集器,您还可以将-XX:InitiatingHeapOccupancyPercent=N为N到某个低值,以使GC几乎连续地运行并发集合,这将消耗更多的CPU周期,但会更快地缩小堆。 这通常不是一个好主意,但对于某些类型的具有大量备用CPU内核但内存不足的机器而言,它是有意义的。

如果您正在使用具有默认暂停时间目标(CMS或G1)的收集器,您还可以放宽该目标以减少对收集器的约束,或者您可以切换并行收集器以在暂停时间内确定占用空间的优先级。

此外,使用Java 9 -XX:-ShrinkHeapInSteps选项可用于更积极地应用前两个选项引起的收缩。 相关的OpenJDK错误 。

请注意,缩小的能力和行为取决于所选的垃圾收集器。 例如,G1只能获得使用 jdk8u20 在堆中间回收未使用的块的能力。

因此,如果需要堆缩小,则应针对特定的JVM版本和GC配置进行测试。

使用PrintAdaptiveSizePolicy GC记录也可以提供洞察力,例如当JVM尝试为年轻一代使用更多内存以实现某些目标时。

还有一个JEP草案让G1更加热切地回报记忆,但作为草案,不确定是否以及何时实施。 它还提到了Shenandoah和具有这种能力的OpenJ9 VM。

在某些情况下,JVM会释放内存,但是(出于性能原因),只要某些内存被垃圾回收,就不会发生这种情况。 它还取决于JVM,操作系统,垃圾收集器等。您可以使用JConsole,VisualVM或其他分析器来监视应用程序的内存消耗。

另请参阅此相关错误报告

这篇文章解释了GC如何在Java 7中工作。简而言之,有许多不同的垃圾收集器可用。 通常,内存是为Java进程保留的,只有一些GC将它释放到系统中(根据我的要求,我认为)。 但是,Java进程使用的内存不会无限增长,因为Xmx选项定义了一个上限(通常为256m,但我认为它取决于OS /机器)。