java线上内存溢出问题排查步骤
⼀般线上遇到⽐较头疼的就是OOM内存溢出问题,我们都会先看错误⽇志,如果错误⽇志能够定位出哪个类对象导致内存溢出,那么我们只需要针对问题修改bug就好。但是很多时候我们单凭⽇志⽆法定位出内存溢出问题,那么我们这时候就需要以下操作来定位问题。
1、top下对当前服务器内存有个⼤致了解
系统数据库有哪四个top后 shift+M俺内存占⽤由⼤到⼩排序,RES是此进程实际占⽤内存,%MEM是占服务器总内存的49.8。
2、利⽤ps命令查看服务pid
[root@speedyao java]# ps -aux|grep java
3、利⽤jstat查看虚拟机gc情况
jstat -gc:util <vmid> [<interval> [<count>]
vmid:虚拟机进程号
interval:采样时间,默认单位是ms
count:采样条数
[root@speedyao java]# jstat -gcutil 17561 1000 10
以上命令代表1秒钟采样1次,总共采样10次。
FULL GC明显⼤于YOUNG GC次数,并且FULL GC次数很频繁,说明程序有⼤内存对象,并且⼀直⽆法释放。
springframework配置4、⽣成dump⽂件,有两种⽅式。 ⼀种是利⽤jmap直接⽣成dump⽂件;另⼀种是利⽤gcore先⽣成core⽂件,再根据core⽂件利⽤jmap⽣成dump⽂件。
(1)先说第⼀种,这种⽐较简单,使⽤这种⽅案的时候请注意:JVM会将整个heap的信息dump写⼊到⼀个⽂件,heap如果⽐较⼤的话,就会导致这个过程⽐较耗时,并且执⾏的过程中为了保证dump的信息是可靠的,所以会暂停应⽤。
[root@speedyao java]# jmap -dump:format=b,file=heap.prof 17561
format=b:表⽰⽣成⼆进制类型的dump⽂件
file=:后⾯写的是输出的dump⽂件路径
17561:jvm进程idoracle的update语法
java下载过程(2)接下来是第⼆种。这⼀种在jmap转换core⽂件的时候⽐较耗时,并且⽣成的dump⽂件⽤mat打开的时候分析结果不太正确,不太好定位问题。所以我建议使⽤第⼀种,虽然会造成服务挂起吧,但是结果总归是正确的。
安卓开发在哪里学利⽤gcore保存服务的内存信息,因为gcore⽐jmap的dump会快很多,也不对线上服务有⼤的影响
[root@speedyao java]# gdb -q --pid=17561
generate-core-file:⽣成内存对象,⽣成的⽂件存储在当前位置,⽂件格式
detach:断开与进程的连接
quit:退出
利⽤jmap将gcore⽂件转换为java的dump⽂件,这⼀步执⾏的⽐较慢,可以⽤nohup执⾏,以防⽌误点Ctrl+C导致退出。
[root@speedyao java]# jmap -dump:format=b,file=heap.prof /usr/bin/java core.17561
format=b:表⽰⽣成⼆进制类型的dump⽂件
file=:后⾯写的是输出的dump⽂件路径
/usr/bin/java:java命令路径,可以通过命令which java 获取这个路径mysql语句over函数
core.17561:表⽰core⽂件路径
6、利⽤MAT(eclipse开发的可以下载eclipse插件,idea开发的可以下载单独的MAT压缩包)分析dump⽂件。当然也可以⽤jdk⾃带的来分析dump⽂件
上图是概要,阴影部分就是⼤内存对象类,点击选择 “list Object”、“with incoming references”,就出现下图。下图就是这个对象的信息,RunMian 就是map对象所在的类,这样就能快速定位出哪个类中的哪个对象出现了内存异常。
下图Histogram这个tab是堆内存占⽐从⼤到⼩排序。
以上就是内存问题排查的⼤致步骤。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论