【发布时间】:2010-10-01 13:20:20
【问题描述】:
我们在 12 核 IBM 机器上的 RedHat Linux 5.2 上创建了一个在 JBoss 4.2.3 中运行的 webapp。最近我们看到响应时间很长,这似乎是由 GC 活动引起的。模式或多或少如下: 所有请求似乎都以正常速率出现,但直到突然所有响应都“刷新”后才发送字节。 同时 gc.log 有这个模式:
// 这里开始无响应 36788.309: [GC [1 CMS-initial-mark: 1919297K(4456448K)] 1969797K(5111808K), 0.1473460 secs] [Times: user=0.15 sys=0.00, real=0.15 secs] 应用程序线程停止的总时间:0.1530790 秒 36788.457:[CMS 并发标记开始] 36793.886:[CMS 并发标记:5.429/5.429 秒](CMS 并发标记产生 46 次) [时间:用户=6.69 系统=0.07,真实=5.43 秒] 36793.886:[CMS-并发-预清洁-启动] (cardTable:15956张卡片,重新扫描15956张卡片,1次迭代) 36793.988:[CMS-concurrent-preclean:0.089/0.101 秒](CMS-concurrent-preclean 产生 9 次) [时间:用户=0.12 系统=0.01,真实=0.10 秒] 36793.988:[CMS 并发中止预清理启动] (cardTable:75张卡片,重新扫描75张卡片,1次迭代) 申请时间:5.6923460秒 应用程序线程停止的总时间:0.0170000 秒 (cardTable:96张卡片,重新扫描96张卡片,1次迭代) (cardTable:207张卡片,重新扫描207张卡片,1次迭代) (cardTable:45张卡片,重新扫描45张卡片,1次迭代) (cardTable:157张卡片,重新扫描157张卡片,1次迭代) (cardTable:88张卡片,重新扫描88张卡片,1次迭代) (cardTable:213张卡片,重新扫描213张卡片,1次迭代) (cardTable:84张卡片,重新扫描84张卡片,1次迭代) (cardTable:143张卡片,重新扫描143张卡片,1次迭代) (cardTable:40张卡片,重新扫描40张卡片,1次迭代) (cardTable:109张卡片,重新扫描109张卡片,1次迭代) (cardTable:77张卡片,重新扫描77张卡片,1次迭代) (cardTable:156张卡片,重新扫描156张卡片,1次迭代) (cardTable:132张卡片,重新扫描132张卡片,1次迭代) (cardTable:119张卡片,重新扫描119张卡片,1次迭代) (cardTable:115张卡片,重新扫描115张卡片,1次迭代) (cardTable:195张卡片,重新扫描195张卡片,1次迭代) (cardTable:163张卡片,重新扫描163张卡片,1次迭代) (cardTable:166张卡片,重新扫描166张卡片,1次迭代) (cardTable:149张卡片,重新扫描149张卡片,1次迭代) (cardTable:218张卡片,重新扫描218张卡片,1次迭代) (cardTable:46张卡片,重新扫描46张卡片,1次迭代) (cardTable:57张卡片,重新扫描57张卡片,1次迭代) (cardTable:213张卡片,重新扫描213张卡片,1次迭代) (cardTable:189张卡片,重新扫描189张卡片,1次迭代) (cardTable:104张卡片,重新扫描104张卡片,1次迭代) (cardTable:60张卡片,重新扫描60张卡片,1次迭代) (cardTable:368张卡片,重新扫描368张卡片,1次迭代) (cardTable:118张卡片,重新扫描118张卡片,1次迭代) (cardTable:129张卡片,重新扫描129张卡片,1次迭代) (cardTable:291张卡片,重新扫描291张卡片,1次迭代) (cardTable:105张卡片,重新扫描105张卡片,1次迭代) (cardTable:63张卡片,重新扫描63张卡片,1次迭代) (cardTable:73张卡片,重新扫描73张卡片,1次迭代) (cardTable:165张卡片,重新扫描165张卡片,1次迭代) (cardTable:69张卡片,重新扫描69张卡片,1次迭代) (cardTable:157张卡片,重新扫描157张卡片,1次迭代) CMS:由于时间原因中止预清理 [37 次迭代,13 次等待,4954 张卡)] 36799.161:[CMS-concurrent-abortable-preclean:2.965/5.173 秒](CMS-concurrent-abortable-preclean 产生了 166 次) [时间:用户=5.12 系统=0.10,真实=5.17 秒] 申请时间:4.9945030秒 36799.172:[GC [YG 占用:572074 K (655360 K)]36799.172:[GC 36799.173:[ParNew 所需的幸存者大小 67108864 字节,新阈值 2(最大 15) - 年龄 1:59654872 字节,总共 59654872 - 年龄 2:26827232 字节,总共 86482104 - 年龄 3:2613360 字节,总共 89095464 - 年龄 4:929600 字节,总共 90025064 - 5 岁:893176 字节,总共 90918240 - 6 岁:795736 字节,总共 91713976 - 7 岁:809240 字节,总共 92523216 - 8 岁:936216 字节,总共 93459432 - 9 岁:971376 字节,总共 94430808 - 10 岁:624472 字节,总共 95055280 - 11 岁:883616 字节,总共 95938896 - 12 岁:817296 字节,总共 96756192 - 13 岁:977992 字节,总共 97734184 - 14 岁:733816 字节,总共 98468000 - 15 岁:654744 字节,总共 99122744 : 572074K->110988K(655360K), 0.1855140 secs] 2491372K->2031059K(5111808K) icms_dc=0 , 0.1866380 secs] [Times: user=0.72 sys=0.00, real=0.19 secs] 36799.359:[重新扫描(并行)(幸存者:12chunks)在第 3 个线程中完成年轻一代重新扫描工作:0.032 秒 在第 2 个线程中完成年轻一代重新扫描工作:0.035 秒 在第 0 个线程中完成年轻一代重新扫描工作:0.035 秒 在第 1 个线程中完成年轻一代重新扫描工作:0.035 秒 在第 1 个线程中完成剩余的根重新扫描工作:0.030 秒 在第 3 个线程中完成剩余的根重新扫描工作:0.033 秒 在第二个线程中完成剩余的根重新扫描工作:0.032 秒 在第 0 个线程中完成剩余的根重新扫描工作:0.042 秒 在第 2 个线程完成脏卡重新扫描工作:0.029 秒 在第 3 个线程完成脏卡重新扫描工作:0.031 秒 在第 0 个线程完成脏卡重新扫描工作:0.019 秒 在第 1 个线程完成脏卡重新扫描工作:0.031 秒 在第 3 个线程中完成的工作窃取:0.000 秒 在第 0 个线程中完成的工作窃取:0.000 秒 在第二个线程中完成的工作窃取:0.000 秒 在第 1 个线程中完成的工作窃取:0.000 秒 , 0.0959640 secs]36799.455: [weak refs processing, 0.0121220 secs] [1 CMS-remark: 1920070K(4456448K)] 2031059K(5111808K), 0.2952350 secs] [Times: user=1.11 sys=0.000 应用程序线程停止的总时间:0.3066430 秒 36799.468:[CMS 并发扫描启动] 36805.824:[CMS 并发扫描:6.355/6.356 秒](CMS 并发扫描产生 515 次) [时间:用户=8.76 系统=0.24,真实=6.35 秒] 36805.824:[CMS-并发-重置-启动] 36805.903:[CMS 并发重置:0.079/0.079 秒](CMS 并发重置产生 0 次) [时间:用户=0.64 系统=0.01,真实=0.07 秒] 申请时间:6.5590510秒 // 关于这里服务器开始发送响应 36806.044:[GC 36806.045:[ParNew 所需的幸存者大小 67108864 字节,新阈值 2(最大 15) - 年龄 1:55456640 字节,总共 55456640 - 年龄 2:54278984 字节,总共 109735624 : 635276K->131072K(655360K), 0.3230430 secs] 2554507K->2089990K(5111808K) icms_dc=0 , 0.3242750 secs] [Times: user=1.02 sys=0.02, real=0.33 secs] 应用程序线程停止的总时间:0.3422430 秒 申请时间:0.7628480秒我们尝试了各种 GC 设置,但最终或多或少都是这样。 我们当前的参数:
-Xms4096m -Xmx5120m -XX:MaxPermSize=384m -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:+PrintClassHistogram -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDetails -XX:ReservedCodeCacheSize=64m -XX:NewSize=768m -XX:SurvivorRatio=4 -XX:+CMSParallelRemarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=10 -XX:+UseTLAB -XX:ParallelGCThreads=4 -XX:+UseParNewGC -XX:MaxGCPauseMillis=1000 -XX:GCTimeRatio=10 -XX:+CMSPermGenSweepingEnabled -XX:+PrintCMSInitiationStatistics -XX:PrintCMSStatistics=1 -XX:+PrintGCTaskTimeStamps -XX:+PrintGCTimeStamps -verbose:gc -XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:+PrintTenuringDistribution我们怎样才能避免反应迟钝?
【问题讨论】:
-
您在生产环境中使用 -verbose:gc 吗?当然,记录所有 GC 活动会增加无响应。
-
是的,我是。但是我读过的所有博客都说 GC 日志不会减慢系统速度。即使确实如此,我猜这种放缓会一直存在。
-
您是否运行了分析器以找出哪些对象正在充斥堆并有助于 GC 运行?
-
不,我们没有。我有点不愿意这样做,因为我不确定在生产机器上运行分析器的影响。