为什么这个特殊的小GC很慢

时间:2015-09-18 12:54:34

标签: java garbage-collection jvm

我们在tomcat 6.0.35和JDK 7u60上运行了Jira 6.3.10应用程序。操作系统是Centos 6.2,内核为2.6.32-220.7.1.el6.x86_64。 我们不时会注意到应用程序中的暂停。我们发现了与GC的相关性。

内存的启动选项为:-Xms16384m -Xmx16384m -XX:NewSize=6144m -XX:MaxPermSize=512m -XX:+UseCodeCacheFlushing -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:ReservedCodeCacheSize=512m -XX:+DisableExplicitGC

问题是我无法解释为什么特定的Minor GC花了将近7秒钟。请参阅以下网址:2015-09-17T14:59:42.485+0000。用户注意到暂停一分钟超过1分钟。

从我在http://blog.ragozin.info/2011/06/understanding-gc-pauses-in-jvm-hotspots.html看到的内容,我认为是Tcard_scan是决定这种缓慢收集的那个,但我不确定,我无法解释为什么会发生这种情况。

2015-09-17T14:57:03.824+0000: 3160725.220: [GC2015-09-17T14:57:03.824+0000: 3160725.220: [ParNew: 5112700K->77061K(5662336K), 0.0999740 secs] 10048034K->5017436K(16148096K), 0.1002730 secs] [Times: user=1.01 sys=0.02, real=0.10 secs]
2015-09-17T14:57:36.631+0000: 3160758.027: [GC2015-09-17T14:57:36.631+0000: 3160758.027: [ParNew: 5110277K->127181K(5662336K), 0.0841060 secs] 10050652K->5075489K(16148096K), 0.0843680 secs] [Times: user=0.87 sys=0.02, real=0.09 secs]
2015-09-17T14:57:59.494+0000: 3160780.890: [GC2015-09-17T14:57:59.494+0000: 3160780.890: [ParNew: 5160397K->104929K(5662336K), 0.1033160 secs] 10108705K->5056258K(16148096K), 0.1036150 secs] [Times: user=0.62 sys=0.00, real=0.11 secs]
2015-09-17T14:58:27.069+0000: 3160808.464: [GC2015-09-17T14:58:27.069+0000: 3160808.465: [ParNew: 5138145K->86797K(5662336K), 0.0844890 secs] 10089474K->5039063K(16148096K), 0.0847790 secs] [Times: user=0.68 sys=0.01, real=0.09 secs]
2015-09-17T14:58:43.489+0000: 3160824.885: [GC2015-09-17T14:58:43.489+0000: 3160824.885: [ParNew: 5120013K->91000K(5662336K), 0.0588270 secs] 10072279K->5045124K(16148096K), 0.0590680 secs] [Times: user=0.53 sys=0.01, real=0.06 secs]
2015-09-17T14:59:03.831+0000: 3160845.227: [GC2015-09-17T14:59:03.832+0000: 3160845.227: [ParNew: 5124216K->89921K(5662336K), 0.1018980 secs] 10078340K->5047918K(16148096K), 0.1021850 secs] [Times: user=0.56 sys=0.01, real=0.10 secs]
2015-09-17T14:59:42.485+0000: 3160883.880: [GC2015-09-17T14:59:42.485+0000: 3160883.880: [ParNew: 5123137K->98539K(5662336K), 6.9674580 secs] 10081134K->5061766K(16148096K), 6.9677100 secs] [Times: user=102.14 sys=0.05, real=6.97 secs]
2015-09-17T15:00:17.679+0000: 3160919.075: [GC2015-09-17T15:00:17.680+0000: 3160919.075: [ParNew: 5131755K->141258K(5662336K), 0.1189970 secs] 10094982K->5107030K(16148096K), 0.1194650 secs] [Times: user=0.80 sys=0.00, real=0.12 secs]
2015-09-17T15:01:20.149+0000: 3160981.545: [GC2015-09-17T15:01:20.149+0000: 3160981.545: [ParNew: 5174474K->118871K(5662336K), 0.1251710 secs] 10140246K->5089067K(16148096K), 0.1255370 secs] [Times: user=0.63 sys=0.00, real=0.12 secs]
2015-09-17T15:03:07.323+0000: 3161088.718: [GC2015-09-17T15:03:07.323+0000: 3161088.719: [ParNew: 5152087K->80387K(5662336K), 0.0782410 secs] 10122283K->5055601K(16148096K), 0.0785610 secs] [Times: user=0.57 sys=0.01, real=0.07 secs]
2015-09-17T15:03:26.396+0000: 3161107.791: [GC2015-09-17T15:03:26.396+0000: 3161107.791: [ParNew: 5113538K->66134K(5662336K), 0.0697170 secs] 10088753K->5044322K(16148096K), 0.0699990 secs] [Times: user=0.48 sys=0.01, real=0.07 secs]
2015-09-17T15:03:47.185+0000: 3161128.580: [GC2015-09-17T15:03:47.185+0000: 3161128.581: [ParNew: 5099350K->62874K(5662336K), 0.0692700 secs] 10077538K->5043879K(16148096K), 0.0695140 secs] [Times: user=0.61 sys=0.02, real=0.07 secs]
2015-09-17T15:04:04.503+0000: 3161145.899: [GC2015-09-17T15:04:04.503+0000: 3161145.899: [ParNew: 5096090K->63684K(5662336K), 0.0709490 secs] 10077095K->5047678K(16148096K), 0.0712390 secs] [Times: user=0.54 sys=0.01, real=0.07 secs]
2015-09-17T15:04:48.013+0000: 3161189.409: [GC2015-09-17T15:04:48.013+0000: 3161189.409: [ParNew: 5096900K->74854K(5662336K), 0.1530160 secs] 10080894K->5061766K(16148096K), 0.1533520 secs] [Times: user=0.76 sys=0.00, real=0.15 secs] 

我们有198GB的RAM。服务器没有主动交换。这个特殊的Jira实例具有相当高的使用率。有一些自动化工具一直在推动这个实例。 服务器上的内存状态:

$ cat /proc/meminfo
MemTotal:       198333224 kB
MemFree:        13194296 kB
Buffers:           93948 kB
Cached:         10236288 kB
SwapCached:      1722248 kB
Active:         168906584 kB
Inactive:       10675040 kB
Active(anon):   163755088 kB
Inactive(anon):  5508552 kB
Active(file):    5151496 kB
Inactive(file):  5166488 kB
Unevictable:        4960 kB
Mlocked:            4960 kB
SwapTotal:       6193136 kB
SwapFree:             12 kB
Dirty:             14040 kB
Writeback:             0 kB
AnonPages:      167534556 kB
Mapped:          1341076 kB
Shmem:              9196 kB
Slab:            2117816 kB
SReclaimable:    1258104 kB
SUnreclaim:       859712 kB
KernelStack:       51048 kB
PageTables:       431780 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    105359748 kB
Committed_AS:   187566824 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      680016 kB
VmallocChunk:   34255555544 kB
HardwareCorrupted:     0 kB
AnonHugePages:  79947776 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        5604 kB
DirectMap2M:     2078720 kB
DirectMap1G:    199229440 kB

在同一台计算机上运行的其他Jira实例未受影响。我们在这台机器上运行了30个Jira实例。

1 个答案:

答案 0 :(得分:3)

一般

这可能是另一个获取资源的过程(或交换增加的开销):

  

有时是OS活动,例如交换空间或网络   GC发生时发生的活动可以使GC成为可能   停顿的时间要长得多。这些暂停可能很少   秒到几分钟。

     

如果您的系统配置为使用交换空间,则操作系统可能会   将JVM进程的非活动内存页面移动到交换空间   释放当前活动进程的内存,这可能是相同的   过程或系统上的不同过程。交换是非常的   昂贵,因为它需要磁盘访问速度慢得多   与物理内存访问相比。所以,如果在垃圾中   收集系统需要执行交换,GC似乎   跑了很长时间。

来源:https://blogs.oracle.com/poonam/entry/troubleshooting_long_gc_pauses

本文还提供了一些可能感兴趣的一般指示。

<强>具体地

但是,在这种情况下,我会说问题更可能是服务器上运行的JVM数量。

30 *个不同的堆加上JVM开销可能会导致大量内存使用。如果总堆分配超过物理内存的75%,则可能会遇到上述问题(交换活动会显示此问题)。

更重要的是,线程CPU争用可能是这里的真正杀手。根据经验,我没有比逻辑CPU数量更多的JVM(如果实例将同时使用)。

另外,我尝试确保GC线程的数量不超过可用虚拟CPU核心数的4倍。

在30 * 18(基于您的评论),这可能是540 GC线程。我假设你的系统没有135个逻辑核心?

如果我对响应能力的要求较低,我可能会选择8比1的比例。但就我在一个系统上而言 - 单独的JVM相互竞争资源。

<强>建议

减少ParallelGCThreads的数量,目的是使总数低于4x阈值。我认为这是不切实际的,将低优先级JVM适当地设置为低值(2)和更高优先级的JVM(可能是4或8)?

另外,我不确定设置ConcGCThreads = 0的含义,因为我假设你没有任何工作线程就不能拥有CMS ......?如果未设置该值,则JVM根据系统决定自身的行为。我希望这也是0设置的行为 - 这可能是共享系统上的一个非常高的值。尝试明确设置。