我有一个通常具有非常健康的垃圾收集统计信息的Java应用程序。终身收藏通常每小时左右发生一次,STW部分只需几分之一秒。但奇怪的是,收藏总是在应用启动的前五分钟内发生。这是一个真正的问题,因为当时CPU使用率已经远高于正常水平(由于最终会缓存的网络调用增加),因此这些暂停总是比正常时间更长,如果我正在做的话,甚至会超过8秒在极重负荷下重启。
以下是JVM args:
-Xms4096m
-Xmx4096m
-XX:PermSize=768m
-XX:MaxPermSize=768m
-XX:SurvivorRatio=6
-XX:NewSize=1024m
-verbose:gc
-XX:-DisableExplicitGC
-XX:+PrintGCDetails
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-XX:+PrintTenuringDistribution
-XX:+HeapDumpOnOutOfMemoryError
-XX:MaxDirectMemorySize=2048m
-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-XX:+PrintConcurrentLocks
-XX:+ExplicitGCInvokesConcurrent
这里的问题是触发这个终身收藏的原因,因为当它发生时,旧版本中几乎有2gb免费。以下是在终身收藏之前正常情况下的使用情况:
concurrent mark-sweep generation total 3145728K, used 2897098K
这是在启动后的几分钟内触发终身收藏之前的用法:
concurrent mark-sweep generation total 3145728K, used 1573655K
我的理解是,只有当旧的几乎满了时才能出现终身收藏;什么可以触发呢?
答案 0 :(得分:1)
CMS的一个关键概念是它应该在用完空间之前开始收集,从而允许它同时运行。如果等到你用完之后它会触发序列停止世界收藏。
因此,有两个阈值可以确定何时提前触发收集。
-XX:CMSInitiatingOccupancyFraction=90 (by default)
-XX+UseCMSInitiatingOccupancyOnly
如果你没有设置这些,那么当它开始使用“metrics”
时,它就会成功我的理解是,只有当旧的几乎满了时才能发生终身收藏;
这就是并行收集器的功能。