我目前正在尝试调整Apache NiFi以使其以高吞吐量流量工作,但我无法避免使用Full GC。
当流程启动时,会出现非常快速的年轻GC,但是在最终触发完整GC之前,他们无法应对分配需求。这种情况发生在不同的堆大小(从8GB到50GB)和基本配置(仅根据oracle documentation配置区域大小和指定线程):
-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转储分析:
查看日志,我注意到为混合GC选择的旧区域的数量始终为零。根据此really useful article,您可以增加 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?如果是这样,我如何设法收集旧区域并为应用程序需要释放足够的内存?
谢谢大家的帮助。