服务器OOM,jvm排查,调优思路!

目录

1.常用参数

2.OOM排查过程步骤

3.堆转储文件分析工具

4.如何优化

1.常用参数

  • 内存相关

    -Xms:最小堆大小,如-Xms256m

    -Xmx:最大堆大小,如-Xmx512m

    -Xmn:新生代大小,如-Xmn是64m

    -XX:NewRatio:新生代与老年代的比例,如–XX:NewRatio=2,老年代过大的时候,Full GC的时间会很长;老年代过小,则很容易触发Full GC,Full GC频率过高。

    -XX:SurvivorRation:设置Eden与Srivivor的大小比例,如-XX:SurvivorRation=8,代表1个Survivor是Eden的1/8,是整个新生代的1/10。

    -Xss:每个线程堆栈大小,如-Xss1m,每个线程都有独立的栈空间,局部变量、参数分配在栈上

    -XX:PermSize: 指JDK1.6定永久代最小内存值,如-XX:PermSize=64M

    -XX:MaxPermSize : 指JDK1.6定永久代最大内存值,如-XX:MaxPermSize=512M

    -XX:MetaspaceSize :指JDK1.7及以后Metaspace扩容时触发FullGC的初始化阈值

    -XX:MaxMetaspaceSize:指JDK1.7及以后Metaspace扩容时触发FullGC的最大阈值

  • GC相关

    -verbose:gc:记录GC运行以及运行时间,用于查看GC是否是应用的瓶颈

    -verbose:class:输出jvm载入类的相关信息,用于诊断找不到类或者类冲突

    -XX:+PrintGCDetails:打印GC详细信息

    -XX:-DisableExplicitGC:禁止显式GC,即禁止程序中System.gc()

    -XX:-UseParallelGC:启用并行GC

    -XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行回收器

    -XX:+UseConcMarkSweepGC:新生代使用ParNew回收器,老年代使用CMS回收器

  • 项目常用

    -XX:+HeapDumpOnOutOfMemoryError:OOM时导出堆快照到文件

    -XX:+HeapDumpPath,OOM时导出文件路径

    -XX:OnOutOfMemoryError:OOM时操作,比如如执行脚本发送邮件

    -XX:+TraceClassLoading:打印加载类的详细信息

       -XX:+PrintCommandLineFlags :这个参数让JVM打印出那些已经被用户或者JVM设置过的详细的XX参数的名称和值。

      -XX:+PrintFlagsFinal  :的结果是一个按字母排序的590个参数表格 

常见配置举例:
   设置:-Xmx3550m -Xms3550m -Xmn2g -Xss128k
   设置:-Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m XX:MaxTenuringThreshold=0
  吞吐量优先的并行收集器,并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等。
    配置:-Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC 
    配置:-Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy 
  响应时间优先的并发收集器,并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间,使用与应用服务器,电信领域等。
    -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
    -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection 
#参数解析

    -XX:PretenureSizeThreshold:直接晋升到老年代的对象大小
    -XX:MaxTenuringThreshold=0:垃圾最大年龄.
    设置0 年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.
    如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活 时间,增加在年轻代即被回收的概率.(最大为15,在对象头中留有四个字节位置存储该值,所以最大为15)。

    -XX:-DisableExplicitGC — 让System.gc()不产生任何作用
    -XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
    -XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值
    -XX:TargetSurvivorRatio:设置幸存区的目标使用率
    -XX:+UseAdaptiveSizePolicy:动态调整java堆中各个区域的大小以及进入老年代的年龄
    -XX:+HandlePromotionFailure:是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden和Survivor区的所有对象都存活的极端情况

##cms收集器启动后 相关参数设置
    注意:并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生"碎片”,使得运行效率降低. 
    CMSFullGCsBeforeCompaction=5:cms在n次GC后,启动内存碎片整理。
    UseCMSCompactAtFullCollection:cms完成后,启动内存碎片整理
    CMSInitiatingOccupancyFraction:老年代使用多少后触发cms 默认68%

2.OOM排查过程步骤

1、先查看应用进程号pid:     ps  -ef | grep  应用名

2、查看pid垃圾回收情况:  jstat  -gc  pid  5000(时间间隔)

即会每5秒一次显示进程号为68842的java进成的GC情况,显示内容如下图:

服务器OOM,jvm排查,调优思路!

结果说明:显示内容说明如下(部分结果是通过其他其他参数显示的,暂不说明):

S0C:年轻代中第一个survivor(幸存区)的容量 (字节) 

S1C:年轻代中第二个survivor(幸存区)的容量 (字节) 

S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节) 

S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节) 

EC:年轻代中Eden(伊甸园)的容量 (字节) 

EU:年轻代中Eden(伊甸园)目前已使用空间 (字节) 

OC:Old代的容量 (字节) 

OU:Old代目前已使用空间 (字节) 

PC:Perm(持久代)的容量 (字节) 

PU:Perm(持久代)目前已使用空间 (字节) 

YGC:从应用程序启动到采样时年轻代中gc次数 

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s) 

FGC:从应用程序启动到采样时old代(全gc)gc次数 

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s) 

GCT:从应用程序启动到采样时gc用的总时间(s) 

NGCMN:年轻代(young)中初始化(最小)的大小 (字节) 

NGCMX:年轻代(young)的最大容量 (字节) 

NGC:年轻代(young)中当前的容量 (字节) 

OGCMN:old代中初始化(最小)的大小 (字节) 

OGCMX:old代的最大容量 (字节) 

OGC:old代当前新生成的容量 (字节) 

PGCMN:perm代中初始化(最小)的大小 (字节) 

PGCMX:perm代的最大容量 (字节)   

PGC:perm代当前新生成的容量 (字节) 

S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比 

S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比 

E:年轻代中Eden(伊甸园)已使用的占当前容量百分比 

O:old代已使用的占当前容量百分比 

P:perm代已使用的占当前容量百分比 

S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节) 

S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节) 

ECMX:年轻代中Eden(伊甸园)的最大容量 (字节) 

DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满) 

TT: 持有次数限制 

MTT : 最大持有次数限制 

3、开启OOM快照: 

-XX:+HeapDumpOnOutOfMemoryError(开启堆快照)

-XX:HeapDumpPath=C:/heap_dump.hprof(保存文件到哪个目录)

3.堆转储文件分析工具

jhat

  这是最原始的分析工具,它会读取堆转储文件,并运行一个小型的HTTP服务器,该服务器运行你通过一系列网易链接查看堆转储信息。

[ciadmin@2-103test_app pos-gateway-cloud]$ jhat heap_dump.hprof 
Reading from heap_dump.hprof...
Dump file created Mon Mar 05 18:33:10 CST 2018
Snapshot read, resolving...
Resolving 751016 objects...
Chasing references, expect 150 dots......................................................................................................................................................
Eliminating duplicate references......................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

找一台带浏览器的机器访问它,http://ip:7000

更多信息见《九、jdk工具之jhat命令(Java Heap Analyse Tool)、jhat之一:对dump的结果在浏览器上展示

 

jvisualvm

jvisualvm的监视(Monitor) 选项卡可以从一个运行中的程序获得堆转储文件,也可以打开之前生成堆转储文件。

更多信息见《八、jdk工具之JvisualVM、JvisualVM之一--(visualVM介绍及性能分析示例)

4.如何优化

虽然 JVM 能够动态感知 CGroups 对容器的内存限制了,但是 JVM 默认的堆大小是限制值的 1/4,这会导致内存的利用率太低了;如此看来,要想充分利用服务器的资源,还要手动调整好 -Xmx 参数,下面是来自网络的一组经验值:

以下参数配置适用于非计算密集型的大部分应用

分配内存 堆配置推荐
1.5G -Xmx1008M -Xms1008M -Xmn336M -XX:MaxMetaspaceSize=128M -XX:MetaspaceSize=128M
2G -Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M
3G -Xmx2048M -Xms2048M -Xmn768M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M
4G -Xmx2688M -Xms2688M -Xmn960M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M
5G -Xmx3392M -Xms3392M -Xmn1216M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
6G -Xmx4096M -Xms4096M -Xmn1536M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
7G -Xmx4736M -Xms4736M -Xmn1728M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
8G -Xmx5440M -Xms5440M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M

内存>=8G 基础配置

-server
-XX:+DisableExplicitGC
-XX:+UseG1GC
-XX:MaxGCPauseMillis=100
-XX:+ParallelRefProcEnabled
-XX:+HeapDumpOnOutOfMemoryError
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCDateStamps
-XX:ErrorFile=/var/app/gc/hs_err_pidp.log
-XX:HeapDumpPath=/var/app/gc
-Xloggc:/var/app/gc/gct.log

内存<8G 基础配置

-server
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
-XX:+CMSClassUnloadingEnabled
-XX:+ParallelRefProcEnabled
-XX:+CMSScavengeBeforeRemark
-XX:+HeapDumpOnOutOfMemoryError
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCDateStamps
-XX:ErrorFile=/var/app/gc/hs_err_pidp.log
-XX:HeapDumpPath=/var/app/gc
-Xloggc:/var/app/gc/gct.log

 

上一篇:Java虚拟机详解(五)------JVM参数(持续更新)


下一篇:Android开发高性能之 (内存优化)