我的JVM基本上是一个火花执行器,它一个接一个地运行任务。一项任务占用大量内存,并且在其生命周期中需要大量内存。

JConsole and JVisualVM report side by side

上面的JVM在带有默认参数的G1GC上运行。正如您在右侧4:25到4:32 PM之间的VisualVM报告中所看到的,峰值是由于执行者运行的每个任务所致(本质上,每个峰值都是由于执行者在执行任务之后拾取新任务而造成的)。前一个完成)。当我在4:35触发手动GC时,我看到堆使用量急剧下降。同样,正如您在JConsole报告的左侧所看到的那样,G1GC从未收集过旧基因世代空间(16:35之前的旧基因世代空间急剧下降是由于手动GC造成的)。

因为我的应用程序是一个批处理作业应用程序,所以如果JVM花大量时间进行GC,我可以。但是,我的内存不足。因此,我想知道如何调整JVM G1GC参数,以便有更频繁的GC(也收集了旧的Gen空间),并且可以用更少的堆空间(XMX)来完成工作。

最佳答案

对于G1,OpenJDK 12功能是迅速将未使用的内存返回给操作系统:

  • JEP 346: Promptly Return Unused Committed Memory from G1 (tracking issue)

  • 如果内存不足,则可能需要控制RSS(从操作系统分配的总内存),而不仅仅是Java堆中的已使用内存。在当前的OpenJDK中使用G1时,(半)手动触发的完整GC似乎是触发RSS减少的唯一方法。 (如果您更改经常发生完整GC的人机工程学,G1的性能将很差。)

    如果您的OpenJDK构建包含Shenondoah collector,那么如果您需要节省内存,尤其是进行一些调整(例如使用-XX:ShenandoahGCHeuristics=compact)时,这可能是一个更好的选择。

    ZGC最终也应该支持返回内存,但是it currently does notpatch adding an -XX:+ZReleaseUnusedHeap option尚未合并。

    10-04 22:35