一些背景信息;
服务器;
具有 130 GB Ram 的新 SLES 12 服务器旨在为大型数据库(150G + 数据)运行 MySQL。
服务器还将托管一些 Java 应用程序。
Java 版本(Oracle 的默认版本)-Java(TM) SE 运行时环境(内部版本 1.7.0-b147)-Java HotSpot(TM) 64 位服务器 VM(内部版本 21.0-b17,混合模式)
我们偶然发现了以下问题;
运行一些特殊的 java 应用程序会使内核/系统 cpu 峰值减慢/停止应用程序一段时间。我通过制作一个简单地随着时间的推移消耗内存并使用一些 cpu 的 Java 应用程序来复制它。
调查显示在减速期间(10000-25000)发生了大量的中断。
每次减速后,Java 都会获得更多内存。将 Java 设置为以固定内存开始似乎也可以减少问题(将 -Xmx 和 -Xms 设置为相同的值)。详细的垃圾收集也表明 GC 正在启动并且可能是触发器。
GC 和内存分配由于某种原因非常昂贵,我们不知道从哪里看。来自 GC 的详细信息:
[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]
在低端 linux 服务器上运行 GC 的相同程序(运行 SLES,来自 SUN 的 Java 1.6.0_11);
[GC 1092288K->253266K(3959488K), 3.0125460 secs]
减速期间的TOP:
top - 11:23:33 up 87 days, 19:55, 5 users, load average: 14.27, 4.50, 10.17
Tasks: 250 total, 39 running, 211 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 71.8%sy, 0.0%ni, 28.2%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 129033M total, 128576M used, 457M free, 1388M buffers
Swap: 32765M total, 13M used, 32752M free, 113732M cached
减速期间的 vmstat(从第 3 行开始);
procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 13552 1714328 1422268 116462260 0 0 10 9 0 0 0 0 100 0 0
1 0 13552 1241780 1422268 116462292 0 0 0 0 240 353 1 0 99 0 0
1 0 13552 695616 1422268 116462292 0 0 0 17 419 431 3 0 97 0 0
55 0 13552 486384 1422268 116462292 0 0 0 2 20228 458 1 57 43 0 0
75 0 13552 476172 1422268 116462300 0 0 0 8 12782 684 0 70 30 0 0
65 0 13552 470304 1422268 116462304 0 0 0 0 13108 792 0 72 28 0 0
为什么高端服务器上的 GC 比低端服务器上的贵?任何想法在哪里寻找线索?
更新 - 调用参数 2012-11-26 调用参数;
java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain
给予
[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]
变成;
java -Xmx4g -Xms4g -XX:+UseParallelGC -verbose:gc -cp "./dest/" UseMemoryMain
给予
[GC 1048640K->265430K(4019584K), 0,0902660 secs]
变成;
java -Xmx4g -Xms4g -XX:+UseConcMarkSweepGC -verbose:gc -cp "./dest/" UseMemoryMain
给予
[GC 1092288K->272230K(3959488K), 0,1791320 secs]
真正有趣的是,今天重新运行而不告诉使用哪种 GC 方法给出了这个;
java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain
给予
[GC 1024064K->259238K(3925376K), 0,0839190 secs]
Java以某种方式改变了默认GC的策略......