1

我目前正在尝试调整 Apache NiFi 以使其与高吞吐量流一起工作,但我无法避免 Full GC。

当流启动时,会发生非常快的年轻 GC,但它们无法应对分配需求,直到最终触发 Full GC。这种情况发生在不同的堆大小(从 8GB 到 50GB)和基本配置(根据oracle 文档只配置了区域大小和指定线程):

-XX:ConcGCThreads=3
-XX:G1HeapRegionSize=16
-XX:InitialHeapSize=34359738368
-XX:MaxHeapSize=34359738368
-XX:ParallelGCThreads=10
-XX:+ParallelRefProcEnabled
-XX:+PrintAdaptiveSizePolicy
-XX:+PrintGC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC

以下是使用 GCViewer 执行的 GC dump 分析:

在此处输入图像描述

查看日志,我注意到为混合 GC 选择的旧区域的计数始终为零。根据这篇非常有用的文章,您可以增加删除InitiatingHeapOccupancyPercent的幅度,并允许标记阶段更早开始。这似乎没有任何影响,因为选择的旧区域的计数仍然为零:

[G1Ergonomics (CSet Construction) finish choosing CSet, eden: 1777 regions, survivors: 251 regions, old: 0 regions, predicted pause time: 216.28 ms, target pause time: 200.00 ms]

根据 oracle 文档,我可以使用一些实验性标志,例如G1MixedGCLiveThresholdPercent=65,但即使我在其他所有内容之前添加UnlockExperimentalVMOptions标志,我也会收到以下错误:

2016-10-10 14:48:14,285 ERROR [NiFi logging handler] org.apache.nifi.StdErr Error: VM option 'G1MixedGCLiveThresholdPercent' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions

基本上,该标志被忽略。

首先,是否是旧区域的非收集触发了完整的 GC?如果是这样,我如何设法收集旧区域并为应用程序需要释放足够的内存?

谢谢大家的帮助。

4

0 回答 0