java线上内存溢出问题排查步骤

摘要:
通常,OOM内存溢出的问题是一个令人头疼的在线问题。我们将首先查看错误日志。如果错误日志可以找到导致内存溢出的对象类,那么我们只需要修改问题的bug。当然,您也可以使用jdk附带的jvisualvm.exe来分析转储文件。上图是一个摘要,阴影部分是大内存对象类。单击并选择“listObject”和“withincomingreferences”,将出现下图。在下图中,直方图的选项卡从最大堆内存到最小堆内存进行排序。

一般线上遇到比较头疼的就是OOM内存溢出问题,我们都会先看错误日志,如果错误日志能够定位出哪个类对象导致内存溢出,那么我们只需要针对问题修改bug就好。但是很多时候我们单凭日志无法定位出内存溢出问题,那么我们这时候就需要以下操作来定位问题。

1、top下对当前服务器内存有个大致了解

java线上内存溢出问题排查步骤第1张

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次。

java线上内存溢出问题排查步骤第2张

FULL GC明显大于YOUNG GC次数,并且FULL GC次数很频繁,说明程序有大内存对象,并且一直无法释放。

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进程id

(2)接下来是第二种。这一种在jmap转换core文件的时候比较耗时,并且生成的dump文件用mat打开的时候分析结果不太正确,不太好定位问题。所以我建议使用第一种,虽然会造成服务挂起吧,但是结果总归是正确的。

利用gcore保存服务的内存信息,因为gcore比jmap的dump会快很多,也不对线上服务有大的影响

[root@speedyao java]# gdb -q  --pid=17561

 java线上内存溢出问题排查步骤第3张

 generate-core-file:生成内存对象,生成的文件存储在当前位置,文件格式pid.core

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 获取这个路径

core.17561:表示core文件路径

6、利用MAT(eclipse开发的可以下载eclipse插件,idea开发的可以下载单独的MAT压缩包)分析dump文件。当然也可以用jdk自带的jvisualvm.exe来分析dump文件

java线上内存溢出问题排查步骤第4张

上图是概要,阴影部分就是大内存对象类,点击选择 “list Object”、“with incoming references”,就出现下图。下图就是这个对象的信息,RunMian 就是map对象所在的类,这样就能快速定位出哪个类中的哪个对象出现了内存异常。

java线上内存溢出问题排查步骤第5张

下图Histogram这个tab是堆内存占比从大到小排序。 

java线上内存溢出问题排查步骤第6张

以上就是内存问题排查的大致步骤。

转载于:https://blog.csdn.net/u010430495/article/details/87283064?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control

免责声明:文章转载自《java线上内存溢出问题排查步骤》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JavaScript 新旧替换六:键值对数据入门系列- ABP 本地化下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

gdb调试

前期准备 一般来说GDB主要调试的是C/C++的程序。在gdb调试之前,必须要把调试信息加到可执行文件中。使用编译 器(cc/gcc/g++)的 -g 参数可以做到这一点。如: gcc -g hello.c -o hello g++ -g hello.cpp -o hello 如果没有-g,将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。...

MAT工具定位分析Java堆内存泄漏问题方法

一、MAT概述与安装 MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题。该工具提供了两种使用方式,一种是插件版,可以安装到Eclipse使用,另一种是独立版,可以直接解压使用。 我把独立版MAT安装包放到了网盘上,方便直接下载———— 链接:https://pan.baidu.com/s/1...

Linux下如何生成core dump 文件(解决segment fault段错误的问题)

Linux下的C程序常常会因为内存访问等原因造成segment fault(段错误),如果此时core dump 的功能是打开的,在运行我们的可执行程序时就会生成一个名为core的文件,然后我们就可以用gdb对core文件来进行调式,还原发生错误的堆栈情况,这对于我们调试bug非常有帮助。 1. 使用  ulimit -a 可以察看当前系统core文件的大...

EF core的原生SQL查询以及用EF core进行分页查询遇到的问题

在用.net core进行数据库访问,需要处理一些比较复杂的查询,就不得不用原生的SQL查询了,然而EF Core 和EF6 的原生sql查询存在很大的差异。 在EF6中我们用SqlQuery和ExecuteSqlCommand进行sql语句的执行,而在EF Core中我们则使用FromSql和ExecuteSqlCommand 一.ExecuteSqlC...

Apache Solr SSRF (CVE-2021-27905)复现

0x00漏洞概述 Apache solr是一个开源的搜索服务,使用java编写,运行在serblet容器的一个独立的全文搜索服务器,是apache luncene项目的开源企业搜索平台。 0x01影响范围 Apache solr <=8.8.2 0x02漏洞复现 1、本次复现使用的是apache solr8.8.1版本,下载完成后解压进入bin目录,...

JavaDump 规格严格

引言 http://www.oschina.net/p/becl/similar_projects?lang=19&sort=view&p=13 对于大型 java 应用程序来说,再精细的测试都难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。JVM 能够记录下...