记一次服务器故障

因为发现服务器报警cpu使用率过高,使用top查看发现load average达到12。

负载高可能的原因:

CPU
内存(包括虚拟内存)
磁盘I/O
检查cpu使用率百分之80,90多。

内存16G使用了一半多,也基本没有问题。

磁盘,因为不存在上传下载,也就没考虑。

java进程占用大多数cpu,可能虚拟机配置有问题。

jstat -gcutil 13821 1000

查看gc状态,发现FGC,每秒基本都会发生一次。

理论上YGC10秒,FGC1min比较正常。

S0: 新生代中Survivor space 0区已使用空间的百分比 S1: 新生代中Survivor space 1区已使用空间的百分比 E: 新生代已使用空间的百分比 O: 老年代已使用空间的百分比 P: 永久带已使用空间的百分比 YGC: 从应用程序启动到当前,发生Yang GC 的次数 YGCT: 从应用程序启动到当前,Yang GC所用的时间【单位秒】 FGC: 从应用程序启动到当前,发生Full GC的次数 FGCT: 从应用程序启动到当前,Full GC所用的时间 GCT: 从应用程序启动到当前,用于垃圾回收的总时间【单位秒】

FGC原因:

· 年老代(Tenured)被写满

· 持久代(Perm)被写满

· System.gc()被显示调用

·上一次GC之后Heap的各域分配策略动态变化

修改持久带大小到256M恢复正常。

服务器配置如下:

JVM_0PTIONS=”-server -XX:+UseConcMarkSweepGC -XX:ParallelCMSThreads=20 -XX:+CMSClassUnloadingEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=80”

export JAVA_OPTIONS=”-Xms2096m -Xmx4000m -Xss333k -Xmn1600m -XX:PermSize=64M -XX:MaxPermSize=256M ${JVM_0PTIONS} -Dmig.apps=${JETTY_APP} -Djetty.host=${JETTY_HOST} -Dserver_name=${JETTY_SERVER_NAME}”

$JETTY_HOME/bin/jetty.sh $* 1>> ${JETTY_LOGS}/jetty_stdout.log 2>>${JETTY_LOGS}/jetty_stderr.log

UseConcMarkSweepGC 并发收集器

XX:ParallelCMSThreads 定义并发CMS过程运行时的线程数

CMSClassUnloadingEnabled 相对于并行收集器,CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,

UseCMSCompactAtFullCollection 因此为了防止堆碎片引起full gc,通过会开启CMS阶段进行合并碎片选项

XX:CMSInitiatingOccupancyFraction 为了在应用程序使用完内存之前完成垃圾收集周期,CMS收集器要比并行收集器更先启动

-XX:CMSFullGCsBeforeCompaction=1 设置多少次full gc后进行内存压缩,由于并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生”碎片”,使得运行效率降低.此值设置运行多少次GC以后对内存空间进行压缩,整理。

回收器选择

 JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动的时候加入相应参数。JDK5.0以后,JVM会根据当前系统配置进行判断。

吞吐量优先的并行收集器