spring 项目排查内存泄露,老年代内存不断增长,分区占100%

这星期在测试大并发的数据上报,测试过程中发现运行一段时间后,服务会卡住,不再响应请求,排查后发现 重启时,内存会不断增加,最终到达3G多卡死。

于是只能导出jvm运行的堆栈信息,分析内存泄露的问题。

首先是一些常用的命令。一类是jdk自带的分析工具,jmap用于分析jvm内存, jstack可以分析线程死锁,分析线程执行情况。还有阿里的 Arthas - Alibaba Java Diagnostic Tool 也是一个非常强大的工具,还能直接修改一些运行的内存类,分析方法执行返回,也是非常强大。

1. 查询java进程

首先 jps 命令可以查看运行中的java进程

 2. jmap 可以分析内存

打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。它的用途是为了展示java进程的内存映射信息,或者堆内存详情。 

可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。

jmap -heap:format=b pid   bin格式  javaversion 1.5

jmap -dump:format=b,file=filename pid javaversion >1.6

jmap -dump:format=b,file=outfile 3024可以将3024进程的内存heap输出出来到outfile文件里,再配合MAT(内存分析工具(Memory Analysis Tool)或与jhat (Java Heap Analysis Tool)一起使用,能够以图像的形式直观的展示当前内存是否有问题。

64位机上使用需要使用如下方式:

jmap -J-d64 -heap pid

spring 项目排查内存泄露,老年代内存不断增长,分区占100%_第1张图片

导出日志快照:jmap -dump:format=b,file=heap.hprof  pid

3. 分析快照:

分析快照有多种工具,比如jhat 、 virualvm 这都是jdk自带的工具。 jhat会分析快照文件,然后在后台起一个web服务,默认是使用7000端口,可以通过浏览器查看快照。

需要注意的是假如快照文件比较大,需要增大jhat的解析内存

用类似这样的命令: jhat -J-d64 -J-mx10g heap.hprof

jhat 分析jmap生成的dump文件 - hopeless-dream - 博客园

通过jdk自带的Java VisualVM对通过jmap导出的dump二进制文件转换堆栈转实例可视化文本内容进行分析 - 小木人印象

        我没有使用上述工具分析,而是使用eclipse一个非常有用的插件: memory analyse,

Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

    需要注意两点,第一点是最新的版本最低要求java11, 我的jdk是java8,所以没有采用最新版本,而是安装的1.8版本, 第二点同样是内存不够的问题,可以修改配置文件,把JVM的堆内存调大

spring 项目排查内存泄露,老年代内存不断增长,分区占100%_第2张图片

spring 项目排查内存泄露,老年代内存不断增长,分区占100%_第3张图片spring 项目排查内存泄露,老年代内存不断增长,分区占100%_第4张图片

       4. 分析

        经过等待后,分析结果是线程池的队列溢出了,我发现不少人遇到过类似的问题,项目里面存在数据产生和数据消费,产生之后提交给线程池完成消费任务,数据消费的速率跟不上产生,于是在线程池的队列里面不断挤压,方法是提高线程池的处理线程数,提高消费的速率,然后就是给队列增加容量,防止无限增长,增加丢弃策略。

         另外一个小tip:命令中增加OOM打印异常堆栈的命令是-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/jvmlogs/

 spring 项目排查内存泄露,老年代内存不断增长,分区占100%_第5张图片

spring 项目排查内存泄露,老年代内存不断增长,分区占100%_第6张图片

你可能感兴趣的:(JAVA,spring,java,后端)