JVM OOM和CPU问题排查

目录

1、JVM调优工具

1.1、jps

1.2、jstat

1.3、jstack

1.4、jinfo 

1.5、jmap

2、OOM排查过程

2.1、OOM原因

2.2、OOM发生区域

2.2.1、Java堆溢出:heap

2.2.2、Java栈溢出:stack

2.2.3、运行时常量溢出:constant

2.2.4、方法区溢出:directMemory

2.3、OOM排查流程

3、CPU排查过程

3.1、核心步骤排查

3.2、CPU飙升原因分析


  • 吞吐量 = CPU运行用户代码时间/(运行用户代码时间+垃圾收集时间);
  • 暂停时间 = 执行垃圾回收时,程序的工作线程被暂停的时间;
  • 内存占用 = java堆所占内存的大小;
  • 收集频率 = 垃圾收集的频次。

1、JVM调优工具

1.1、jps

        查看Java进程的工具,可获取所需进程的PID,跟Linux下的ps命令类似。

        列出正在运行的JVM的PID,以及JVM的执行主类、JVM启动参数等。

1.2、jstat(虚拟机统计信息监视工具)

        显示虚拟机进程中的类装载、内存、垃圾收集等运行数据。

        Jstat [option] VMID 打印间隔时间(ms) 打印次数

  • -class:查询类加载器信息
  • -complier:JIT相关信息
  • -gc:GC堆状态
  • -gcnew:新生代统计信息
  • -gcutil:GC堆统计汇总信息

1.3、jstack

        查看当前Java程序内线程详细堆栈信息的工具,用于生成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)

1.4、jinfo 

        查看JVM参数、动态修改部分JVM参数。

        Jinfo [option] pid

  1. -flag<name> 打印指定名称的参数
  2. -flag[+|-]<name> 打开或关闭参数
  3. -flag<name>=<value> 设置参数
  4. -flags 打印所有参数
  5. -sysprops 打印系统配置

1.5、jmap

用于生成堆转储快照dump文件,常用于分析OOM异常情况。

-dump:生成java堆的dump文件

jhat [option] dumpfile:分析jmap生成的dump文件。

2、OOM排查过程

2.1、OOM原因

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
  • 资源使用之后没有及时关闭,导致对象无法被GC回收;
  • 代码中存在死循环或循环产生过多重复的对象实体;
  • 使用的第三方软件中的BUG;
  • 启动参数内存值设定的过小;

2.2、OOM发生区域

2.2.1、Java堆溢出:heap

        java.lang.OutofMemoryError:Java heap space

        原因:内存泄露、JVM内存小、创建太多的对象没有释放。

        相关JVM参数:-Xms、-Xmx

2.2.2、Java栈溢出:stack

        java.lang.StackOverflowError,常发生于递归。

        java.lang.OutofMemoryError: unable to create new native thread,常发生于创建太多线程。

        相关JVM参数:-Xss,表示每个线程的堆栈大小。

2.2.3、运行时常量溢出:constant

        java.lang.OutofMemoryError: PermGen space。

        运行时常量保存在方法区,存放的主要是编译器生成的各种字面量和符号引用,但是运行期间也可能将新的常量放入池中。

        -XX:PermSize:设置持久代(perm gen)初始值,默认值为物理内存的1/64

        -XX:MaxPermSize:设置持久代最大值,默认为物理内存的1/4

2.2.4、方法区溢出:directMemory

        java.lang.OutofMemoryError: PermGen space。

        方法区主要存储被虚拟机加载的类信息,如类名、访问修饰符、常量池、字段描述、方法描述等。目前很多框架,如Spring、Hibernate等会在运行过程中动态生成类,所以方法区也有可能发生OOM。

2.3、OOM排查流程

需要先设置JVM参数,设定当发生OOM的时候自动生成dump出堆信息:

  • 开启堆快照:-XX:+HeapDumpOnOutOfMemoryError
  • OOM时日志记录文件位置:-XX:HeapDumpPath=/usr/local/error.hprof

1、先查看应用pid号:ps -ef|grep 应用名/java;

        或者使用jps查看JVM中运行的进程状态信息;

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

        查看堆内存各部分的使用量,加载类的数量以及GC的情况

3、使用jmap -histo:live pid 显示堆中的详细信息

4、使用jmap -dump:format=b,file=heapdump.phrof pid生成堆存储快照,然后将快照文件使用jvisualvm进行分析;

3、CPU排查过程

3.1、核心步骤排查

  1. 执行”top”命令:查看所有进程占系统CPU的排序。找出进程号(PID)。
  2. 执行”top -Hp PID”命令:查看java进程下的所有线程占CPU的情况。
  3. 执行printf “%x\n 10”命令 :后续查看线程堆栈信息展示的都是十六进制,所以需要把线程号转成16进制。例如, printf "%x\n 10"->打印:a,那么在jstack中线程号就是0xa.
  4. 执行 “jstack PID | grep 线程ID”:查找某进程下->线程ID(jstack堆栈信息中的nid)=0xa的线程堆栈信息。如果“"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable”,第一个双引号圈起来的就是线程名,如果是“VM Thread”这就是虚拟机GC回收线程了
  5. 1、执行“jstat -gcutil 进程号” 统计间隔毫秒 统计次数(缺省代表一致统计)”,查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大->确认Full GC!                           
  6. 2、也可以使用“jmap -heap 进程ID”查看一下进程的堆内从是不是要溢出了,特别是老年代内从使用情况一般是达到阈值(具体看垃圾回收器和启动时配置的阈值)就会进程Full GC。
  7. 执行“jmap -dump:format=b,file=filename 进程ID”,导出某进程下内存heap输出到文件中。可以通过eclipse的mat工具查看内存中有哪些对象比较多。

3.2、CPU飙升原因分析

  • 内存消耗过大,导致Full GC次数过多

  • 代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢

  • 由于锁使用不当,导致死锁

  • 随机出现大量线程访问接口缓慢

  • 某个线程由于某种原因而进入WAITING状态,此时该功能整体不可用,但是无法复现

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

部分内容截取自网络,如有侵权,联系作者删除。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值