首页 文章

低暂停收集器 - 并发模式故障

提问于
浏览
1

我们的一个应用程序在 生产环境 中遇到问题 .

VM配置如下

-XX:MaxPermSize = 300M -Xms2560M -Xmx2560M -Xloggc:/app/log/gc-admin-20120619-123754.log -verbose:gc -XX:PrintGCTimeStamps -XX:PrintGCDetails -XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction = 80 - XX:DisableExplicitGC -XX:CMSMaxAbortablePrecleanTime = 8000

我错过并将应用的两个选项是XX:PermSize - 当使用CMSInitiatingOccupancyFraction时,应与MaxPermSize(推荐)UseCMSInitiatingOccupancyOnly相同,否则您指定的值不会粘!

然而,随着pipleline的这些变化我不那么自信它将解决我的问题 .

我看到并发模式失败但是当失败发生时,停止世界收集需要永恒 . 目前我有点困惑为什么!!

这是一些样本

168427.476:[GC [1 CMS-initial-mark:2135988K(2578880K)] 2141041K(2617216K),3.1029210 secs] [次:用户= 0.02 sys = 0.01,real = 3.10 secs] 168430.596:[CMS-concurrent-mark-开始] 168441.309:[GC 168441.309:[ParNew:36520K-> 36520K(38336K),0.0000210 secs] 168441.309:[CMS168747.453:[CMS-concurrent-mark:309.313 / 316.857 secs] [次:用户= 5.75 sys = 2.89 ,real = 316.81 secs](并发模式失败):2561882K-> 1310927K(2578880K),767.0309740 secs] 2598402K-> 1310927K(2617216K),[CMS Perm:96774K-> 96171K(158792K)],767.0379030 secs] [次: user = 3.87 sys = 5.06,real = 766.92 secs]

令我担心的是整个STW集合的时间是766.92secs,但只有“user = 3.87 sys = 5.06”的CPU时间,那么剩下的时间里发生了什么?这是我很困惑的地方,我无法想象停止应用程序中的所有线程需要那么久!吵架也许??

169545.325:[GC [1 CMS-initial-mark:2141069K(2578880K)] 2166025K(2617216K),0.0530140 secs] [次:用户= 0.05 sys = 0.00,real = 0.06 secs] 169545.379:[CMS-concurrent-mark-开始] 169558.635:[CMS-并发标记:10.407 / 13.256秒] [时间:用户= 7.58 sys = 0.53,实际= 13.25秒] 169558.635:[CMS-concurrent-preclean-start] 169558.684:[CMS-concurrent-preclean :0.048 / 0.048秒] [时间:用户= 0.01 sys = 0.00,实际= 0.05秒] 169558.684:[CMS-concurrent-abortable-preclean-start] 169560.544:[GC 169560.544:[ParNew169560.605:[CMS-并发 - abortable-preclean:0.210 / 1.921 secs] [时间:用户= 0.93 sys = 0.05,实际= 1.92秒] 169560.846:[GC [YG占有率:1906 K(38336 K)] 169560.846:[重新扫描(平行),0.0046910秒] 169560.851:[弱refs处理,0.0000990秒] [1 CMS-remark:2350428K(2578880K)] 2352335K(2617216K),0.0048570 secs] [次:用户= 0.01 sys = 0.00,real = 0.01 secs] 169560.853:[CMS-concurrent -sweep-start] 169568.204:[CMS-concurrent-sweep:7.351 / 7.351秒] [时间:用户= 0.91 sys = 0 . 09,实际= 7.34秒] 169568.204:[CMS-concurrent-reset-start] 169568.211:[CMS-concurrent-reset:0.007 / 0.007 secs] [时间:用户= 0.01 sys = 0.00,实际= 0.01秒]

这个没有问题

252247.318:[GC [1 CMS-initial-mark:2069401K(2578880K)] 2075094K(2617216K),1.5311840 secs] [次:用户= 0.01 sys = 0.00,real = 1.53 secs] 252248.849:[CMS-concurrent-mark-开始] 252350.336:[GC 252350.336:[ParNew:20984K-> 4222K(38336K),12.2251190 secs] 252362.561:[CMS252520.780:[CMS-concurrent-mark:161.376 / 271.922 secs] [次:用户= 12.56 sys = 1.72 ,real = 271.89 secs](并发模式故障):2232372K-> 1061586K(2578880K),407.2310250 secs] 2240205K-> 1061586K(2617216K),[CMS Perm:97525K-> 97381K(160480K)],419.4586450 secs] [次: user = 4.23 sys = 2.99,real = 419.39 secs]

然后又是另一个“时代:用户= 4.23 sys = 2.99,真实= 419.39秒” . CPU时间很小“user = 4.23 sys = 2.99”,但总时间为“419.39” . 什么可能导致VM挂起这么久?理想情况下,在10秒以下的STW系列中应收集2.5克!!

我要降低门槛CMSInitiatingOccupancyFraction,但我不认为收集时间就像它会有所帮助!有些收藏品运行顺畅,有些收藏品不像我说的那样,当全面停止世界时,它让我担心的时机 .

我看过https://blogs.oracle.com/jonthecollector/entry/what_the_heck_s_a

我们正在使用jdk6 .

以前有人经历过类似的事吗?

3 回答

  • 2

    正如您所观察到的,当并发模式失败时,会回落到世界各地 . 我的理解是,这可以使用标记扫描紧凑的收集器而不是更有效的复制收集器来完成 .

    这并不能完全解释为什么收集这么长时间 . 然而,VM捶打这是一个看似合理的理论,您的证据支持这一点......但您需要获得一些操作系统级别的VM交换/寻呼速率测量 . (如果JVM会导致颠簸,那么当堆已满时,在完全垃圾收集期间最有可能是最糟糕的 . )

    回到导致并发模式失败的原因,您链接的博客说明了最有可能发生的事情:

    • 你的堆是满的,或者

    • 对象分配率太高,或

    • 对象分配率太可变,或

    • 以上的一些组合 .

    建议的解决方案是:

    • 增加堆大小 .

    • 减少CMSInitiatingOccupancyFraction值

    • 增加CMSIncrementalSafetyFactor值

    另一个是切换到吞吐量收集器,并且在完全收集时偶尔会出现“长时间”暂停 .

    如果问题是虚拟机颠簸,那么你就是在一块坚硬的地方之间 . 您已经相对于计算机或虚拟机可用的物理RAM量过度分配了虚拟内存 . 您可以选择为机器/虚拟机提供更多RAM,或者通过减少堆大小,停止服务和应用程序等来减少系统的虚拟内存使用量 .

    (请注意,无论您是否使用虚拟化,都可能发生虚拟内存抖动 . 就像虚拟化一样,过度分配内存的诱惑力更强......)

  • 1

    您的应用程序是否在虚拟机上运行?

    解释可能是您的主机过载或交换,这会阻止VM工作并看到发生的事情 .

  • 0

    永久代( PermSize )用于反映VM本身,例如类对象和方法对象 . 这些反射物体直接分配到永久世代中,并且其尺寸独立于其他世代 . 通常,可以忽略此代的大小,因为默认大小足够 . 但是,加载许多类的程序可能需要更大的永久代 .

    默认情况下, MaxPermSize 对于-client为32mb,对于-server为64mb . 但是,如果未同时设置 PermSizeMaxPermSize ,则除非需要,否则整个堆不会增加 . 当您设置 PermSizeMaxPermSize (例如,192mb)时,额外的堆空间将在启动时分配,并将保持分配状态 .

    尝试调整两个VM参数,它可能会解决您的问题 .

    -XX:PermSize=300m -XX:MaxPermSize=300m
    

相关问题