Full GC(堆检查启动GC)

6

我在我们的生产环境JVM上苦于追踪“Full GC”。每天午夜左右,停止-对-所有(STW)事件会发生,但没有明显的原因,持续10-11秒钟。以下是垃圾回收日志:

Java HotSpot(TM) 64-Bit Server VM (25.131-b11) for windows-amd64 JRE (1.8.0_131-b11), built on Mar 15 2017 01:23:53 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 16584284k(13074876k free), swap 23137624k(18439472k free)
CommandLine flags: -XX:GCLogFileSize=1024000 -XX:InitialHeapSize=11811160064 -XX:+ManagementServer -XX:MaxHeapSize=11811160064 -XX:NumberOfGCLogFiles=10 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseGCLogFileRotation -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
...
2020-01-17T00:00:04.411+0200: 113734.053: [GC (Heap Inspection Initiated GC) [PSYoungGen: 522474K->146371K(3387904K)] 6946079K->6573263K(11077632K), 0.1786961 secs] [Times: user=0.67 sys=0.02, real=0.18 secs] 
2020-01-17T00:00:04.592+0200: 113734.233: [Full GC (Heap Inspection Initiated GC) [PSYoungGen: 146371K->0K(3387904K)] [ParOldGen: 6426892K->3217828K(7689728K)] 6573263K->3217828K(11077632K), [Metaspace: 81937K->81809K(1126400K)], 11.4447857 secs] [Times: user=44.06 sys=0.20, real=11.44 secs] 
"Heap Inspection Initiated GC" 是什么意思?是谁发起了这个检查,为什么要这样做?除了一些我们不使用的工具(如jmap、jmc等)会引起这种情况之外,我没有找到任何有意义的信息。
非常感谢任何提示或指导。

不要误会我的意思,但是你正在使用ParallelGC,却想知道为什么会出现大的STW?只是好奇... - Eugene
是的,这就是ParallelGC。实际上问题是,“Heap Inspection Initiated GC”引起的实际原因是什么。显然,原因不是堆不足并需要清理。在此VM中有大量堆。 - Dima
1
你必须使用 @ 标记我,这样我才知道你做出了回应。你或许有一个可以做到这一点的代理吗?也许会触发 这个 - Eugene
@Eugene - 好的,这让我想起了什么。我们使用这个进行监控。我会去看一下。如果我理解正确,这个GC可能是由外部进程引起的而不是本身引起的?这就是这个cause的意思吗? - Dima
确切地说,就我所见,有各种不同的地方可以触发这个:代理、jmap、jfr、SIGBREAK - Eugene
2个回答

4

JVM代理可以触发堆检查。要了解当前时刻对象的存活状态,您需要触发Full GC调用。我猜在Shenandoah和/或ZGC的情况下,这将更加“便宜”,因为它们与您的应用程序并发工作。更有趣的是,至少在理论上,并发GC不需要触发所有阶段(标记就足够了)来查找活动和/或死亡的内容。但是,我怀疑它们也会压缩

如果您真的关心STW事件,则ParallelGC可能不是一个很好的选择。垃圾算法名称中的Parallel应该引起警惕:它的所有阶段都与应用程序并行,而不是并发。


1
谢谢您的线索!问题在于代理程序(在我们这里是"perfino")。它的默认设置之一(每隔一段时间记录堆快照)被设定为24小时。这导致在受监控的JVM上每天午夜进行Full GC。这是个坏主意。@Ingo Kegel - 提醒您知晓。 - Dima

3

谢谢,我看到了这些...但是我们不使用任何外部进程来触发运行中的VM上的GC。 - Dima
1
@Dima,你显然是错的 - Andreas
是的,我错了,因为我没有意识到分析器代理能够做到这一点。 - Dima
除非您明确启用堆统计信息,或者使用 jcmd <pid> JFR.dump path-to-gc-roots=true 命令转储记录,否则 JFR 不会导致完整的 GC。 - Kire Haglin
@KireHaglin 是的,这正是链接答案所说的,那么你的观点是什么? - Andreas
只是想澄清一下。我认为“答案:是”是放在那里的,以帮助那些不跟随链接的人。 - Kire Haglin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接