Linux使用运行Java GC的系统/内核CPU

Linux使用运行Java GC的系统/内核CPU,java,linux,garbage-collection,jvm,Java,Linux,Garbage Collection,Jvm,Som背景信息 服务器 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

Som背景信息

服务器

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
新的SLES 12服务器,具有130 GB Ram,用于为大型数据库(150G+数据)运行MySQL

服务器还将承载一些Java应用程序

Java版本(Oracle默认)-Java(TM)SE运行时环境(build 1.7.0-b147)-Java HotSpot(TM)64位服务器虚拟机(build 21.0-b17,混合模式)

我们无意中发现了以下问题

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
运行一些特殊的java应用程序会使内核/系统cpu峰值在一段时间内减慢/停止应用程序。我通过制作一个Java应用程序来复制它,该应用程序只是随着时间的推移消耗内存并使用一些cpu

调查显示,减速期间的中断次数较多(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)

减速期间的顶部:

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
java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain
给予

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]
[GC 1048640K->265430K(4019584K), 0,0902660 secs]
[GC 1092288K->272230K(3959488K), 0,1791320 secs]
[GC 1024064K->259238K(3925376K), 0,0839190 secs]
改为

java -Xmx4g -Xms4g -XX:+UseParallelGC -verbose:gc -cp "./dest/" UseMemoryMain
java -Xmx4g -Xms4g -XX:+UseConcMarkSweepGC -verbose:gc -cp "./dest/" UseMemoryMain
给予

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]
[GC 1048640K->265430K(4019584K), 0,0902660 secs]
[GC 1092288K->272230K(3959488K), 0,1791320 secs]
[GC 1024064K->259238K(3925376K), 0,0839190 secs]
改为

java -Xmx4g -Xms4g -XX:+UseParallelGC -verbose:gc -cp "./dest/" UseMemoryMain
java -Xmx4g -Xms4g -XX:+UseConcMarkSweepGC -verbose:gc -cp "./dest/" UseMemoryMain
给予

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]
[GC 1048640K->265430K(4019584K), 0,0902660 secs]
[GC 1092288K->272230K(3959488K), 0,1791320 secs]
[GC 1024064K->259238K(3925376K), 0,0839190 secs]
真正有趣的是,今天重新运行而不告诉使用哪种GC方法会产生这种效果

给予

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]
[GC 1048640K->265430K(4019584K), 0,0902660 secs]
[GC 1092288K->272230K(3959488K), 0,1791320 secs]
[GC 1024064K->259238K(3925376K), 0,0839190 secs]

Java在某种程度上改变了默认GC的策略…

垃圾收集确实是一个棘手的话题。 为了给出最佳答案,您应该发布用于调用java的完整命令行

正如您所说的,使用GC开关搁浅会有所帮助。原因是,对于现在使用的许多应用程序来说,默认设置很不幸不是最优的。对于许多需要快速响应的应用程序,由于它们是交互式的,因此参数

-XX:+UseConMarkSweepGC

会有很大的不同

值得注意的是,使用您提到的JVM,使用更大的堆(比方说更大的10GB)总是需要一些调整。查看您拥有的GC日志,观察在使用GC选项时行为的变化。我建议尝试不同的收集器策略(如CMS或G1),也可以使用Eden空间的配置(如Xmn)


最后,但并非最不重要的一点是,您可以使用探查器调查应用程序对内存做了什么。也许代码可以改进,因此可以避免大量GC。

简单地强制应用程序使用并行1 GC就可以起到作用-XX:+UseParallelGC[GC 1048640K->265430K(4019584K),00902660秒]谢谢,我已经更新了发布参数。当我今天在没有GC参数的情况下重新运行示例应用程序时,JVM改变了策略,默认情况下GC是“快速的”。