问题描述
我有一个Java应用程序,通常具有非常健康的垃圾收集统计信息。终身收藏通常每隔一小时左右发生一次,STW部分只需要几分之一秒。但奇怪的是,收集总是在应用程序启动的前五分钟内发生。这是一个真正的问题,因为那时CPU使用率已经远远高于正常水平(因为网络调用最终会被缓存),所以这些暂停总是比平时长,甚至超过8秒,如果我正在做在极重的负载下重新启动。
I have a Java application that normally has very healthy garbage collection statistics. A tenured collection normally happens every hour or so and the STW portions take just fractions of a second. But strangely a collection always happens within about the first five minutes of app startup. This is a real problem because at that time, CPU usage is already much higher than normal (due to increased network calls that eventually get cached), so these pauses are always longer than normal and even run past 8 seconds if I'm doing a restart under extremely heavy load.
以下是JVM参数:
Here are the 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的免费版本。以下是正常情况下的使用情况,直到持久性集合:
The question here is what triggers this tenured collection since there is almost 2gb free in old gen when it occurs. Here's the usage under normal circumstances right before a tenured collection:
concurrent mark-sweep generation total 3145728K, used 2897098K
以下是在启动的前几分钟内触发持久集合之前的用法:
And here's the usage just before a tenured collection is triggered within the first few minutes of startup:
concurrent mark-sweep generation total 3145728K, used 1573655K
我的理解是,只有当老的电池已满时才会出现持久性收集;什么能触发它呢?
My understanding is that a tenured collection should only occur when old gen is nearly full; what could trigger it otherwise?
推荐答案
CMS的一个关键概念是它应该在空间用完之前开始收集,从而允许它同时运行。如果它等到你用完了,它会触发连续停止世界收藏。
A key concept of the CMS is that it should start collecting before you run out of space, thus allowing it to run concurrently. If it waited until you ran out it would trigger a serial stop the world collection.
因此,有两个阈值可以确定何时
For this reason there is two thresholds to determine when to trigger a collection prematurely.
-XX:CMSInitiatingOccupancyFraction=90 (by default)
-XX+UseCMSInitiatingOccupancyOnly
如果您没有设置这些,那么在开始使用度量标准 / p>
If you don't set these, it will work out when it a good time to start using "metrics"
这是Parallel Collector的功能。
This is what the Parallel Collector does.
这篇关于没有明显原因开始的终身收藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!