JVM常见线上问题:CPU 100%、内存泄露问题排查

JVM线上CPU 100%与内存泄露问题排查

一、CPU 100% 问题排查

1.1、找到 cpu 占有率最高的 java 进程号

使用命令: top -c 显示运行中的进程列表信息, shift + p 使列表按 cpu 使用率排序显示。

PID = 2227 的进程,cpu 使用率最高

1.2、根据进程号找到 cpu 占有率最高的线程号

使用命令: top -Hp {pid} ,同样 shift + p 可按 cpu 使用率对线程列表进行排序。

10转16
[root@localhost ~]$ printf %x 2228
8b4
16转10
[root@localhost ~]$ printf %d 0x8b4
2228

PID = 2228 的线程消耗 cpu 最高,十进制的 2228 转成十六进制 8b4

1.3、利用 jstack 生成虚拟机中所有线程的快照

jstack -l {pid} > {文件位置}/*.stack

1.4、线程快照分析

把快照下载到本地进行分析,也可直接在 Linux 上分析,命令:

cat 2227.stack |grep '8b4' -C 5

至此定位到问题:

1.5、小结

找到 CPU 使用了最高的进程,利用 jstack 命令生成该进程下所有线程快照文件,分析快照文件查找问题。

二、内存泄露问题排查

2.1,找到内存占有率最高的进程号

使用命令: top -c 显示运行中的进程列表信息, shift + m 按内存使用率进行排序。

可以看到进程号: 2527,占用内存最高。

2.2,利用 jmap 生成堆转储快照

命令:

jmap pwdrmat=b,file={path} {pid}

这里使用kill -3也可以   个人推荐这个
kill -3 {PID}

堆转储快照文件路径: /opt/heapdump_2527.hprof

2.3,利用 MAT 分析堆转储快照

将 heapdump_2448.phrof 下载到本地,利用 MAT 进行分析,定位问题。

2.4,小结

找到内存使用率最高的进程,利用 jmap 生成该进程的堆转储快照,利用堆转储快照分析工具分析问题。

三,配置自动生成 Dump 快照文件(建议配置上)

发生 OOM 时,没配置自动生成 Dump 快照文件不就很尴尬吗?其实在很多时候我们是不知道何时会发生 OOM,所以需要在发生 OOM 时自动生成 dump 文件。其实很简单,只需要在启动时加上如下参数即可。

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/dump/heapdump.hprof -XX:OnOutOfMemoryError=/opt/restart.sh

-Xms: 初始堆大小。默认 (MaxHeapFreeRatio 参数可以调整) 空余堆内存小于 40%时,JVM就会增大堆直到 -Xmx 的最大限制。

-Xmx: 最大堆大小。默认 (MaxHeapFreeRatio 参数可以调整) 空余堆内存大于 70% 时,JVM会减少堆直到 -Xms 的最小限制。

-XX:+HeapDumpOnOutOfMemoryError:表示当 JVM 发生 OOM 时,自动生成 DUMP 文件 最重要的参数。

-XX:HeapDumpPath:(可选)表示生成 DUMP 文件的路径, 可以指定文件名称,

-XX:HeapDumpPath=${目录}/java_heapdump.hprof。若不指定文件名,默认为:java_pid_date_time_heapDump.hprof

-XX:OnOutOfMemoryError:(可选)表示 OOM 时 需要触发的脚本,比如 重启动作,发送告警等等。

四,总结

4.1 大体操作步骤

1、先找到对应的进程: PID
2、生成线程快照 stack (或堆转储快照: hprof )
3、分析快照(或堆转储快照),定位问题

4.2 JVM 常用命令

jps:列出正在运行的虚拟机进程

jstat:监视虚拟机各种运行状态信息,可以显示虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据

jinfo:实时查看和调整虚拟机各项参数

jmap:生成堆转储快照,也可以查询 finalize 执行队列、Java 堆和永久代的详细信息

jstack:生成虚拟机当前时刻的线程快照

jhat:虚拟机堆转储快照分析工具

4.3,内存泄露、内存溢出和 CPU 100% 关系

五、附加常用命令

线上JVM内存分析
1)查看java占用率最高的几条线程
top -H -p  pid 查找最高线程号

10转16
printf %x 2228(线程号)

可以找到指定异常线程的代码所在
jstack 进程号(71983) | grep 16进制线程号(11a8b) -A90  


2)查看堆内存使用情况(memory-info.log为具体文件路径)
jmap -heap PID > memory-info.log

3)查看gc回收情况(gc.log为具体文件路径)
jstat -gcutil PID 1000 20 > gc.log

4)查看JVM存活时长(uptime.log为具体文件路径)
jcmd PID VM.uptime > uptime.log

5)导出dump文件(heap.hprof为具体文件路径)
jmap -dump:live,format=b,file=heap.hprof PID

6)导出堆栈,线程快照(jstack.log为具体文件路径)
jstack -l PID > jstack.log

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值