Jim*_*Jim 36 java garbage-collection memory-management
当垃圾收集器运行并释放内存时,此内存会返回到操作系统,或者它是否作为进程的一部分保留.我的印象是,内存从未实际发布回操作系统,而是作为内存区/池的一部分保留,以便由同一进程重用.
结果,进程的实际内存永远不会减少.一篇提醒我的文章是这篇文章和Java的Runtime是用C/C++编写的,所以我想同样的事情适用于此?
更新
我的问题是关于Java.我提到C/C++,因为我假设Java的分配/解除分配是由JRE使用某种形式的malloc/delete完成的
the*_*472 52
在热点JVM不释放内存返回给操作系统,但这样做不情愿,因为调整堆是昂贵的,它假定,如果你需要的堆一旦你会再次使用它.
您可以通过设置来使其更积极,-XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30这将允许它在GC周期后花费更多的CPU时间来收集和约束已分配但未使用的堆内存量.
假设您正在使用并发收集器,您还可以将-XX:InitiatingHeapOccupancyPercent=NN 设置为某个较低的值,以使GC几乎连续地运行并发收集,这将消耗更多的CPU周期,但会更快地缩小堆.这通常不是一个好主意,但在某些类型的具有大量备用CPU内核但内存不足的机器上它是有意义的.
如果您正在使用具有默认暂停时间目标(CMS或G1)的收集器,您还可以放宽该目标以减少对收集器的约束,或者您可以切换并行收集器以在暂停时间内确定占用空间的优先级.
此外,使用Java 9 -XX:-ShrinkHeapInSteps选项可以更积极地应用前两个选项引起的收缩.相关的OpenJDK错误.
请注意,缩小的能力和行为取决于所选的垃圾收集器.例如,G1只能获得使用 jdk8u20 在堆中间回收未使用的块的能力.
因此,如果需要堆缩小,则应针对特定的JVM版本和GC配置进行测试.
GC Logging with PrintAdaptiveSizePolicy也可以提供洞察力,例如当JVM尝试为年轻一代使用更多内存以实现某些目标时.
还有一个JEP草案让G1更加热切地回报记忆,但作为草案,不确定是否以及何时实施.它还提到了Shenandoah和具有这种能力的OpenJ9 VM.
如果您使用 G1 收集器并偶尔调用 System.gc()(我每分钟调用一次),Java 将可靠地缩小堆并将内存返还给操作系统。
从 Java 12 开始,如果应用程序空闲,G1 会自动执行此操作。
我建议将这些选项与上述建议结合使用,以获得非常紧凑的驻留进程大小:
-XX:+UseG1GC -XX:MaxHeapFreeRatio=30 -XX:MinHeapFreeRatio=10
Run Code Online (Sandbox Code Playgroud)
几个月来,每天都在使用这些选项与动态加载和卸载类的大型应用程序(一个完整的基于 Java 的客户操作系统)一起使用这些选项 - Java 进程几乎总是保持在 400 到 800 MB 之间。