在平时开发、测试过程中、甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题。我们需要找造成内存问题的原因。一般有两种情况:
1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;
2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。
以上是处理Java堆问题的思路,这里以 Elasticsearch 为例子,在 CentOS 系统下,去搞 es 的 JVM 的 heap dump 的 debug 配置。
主要过程:
1、使用 jmap 去 dump 出服务的 heap dump
2、使用 MAT 查看该 heap dump
下面是填坑记录。
工具安装
主要需要 jmap 和 MAT(内存分析工具(Memory Analysis Tool)这两款工具。
1、安装 jmap
sudo yum install java-1.8.0-openjdk-devel-debug
jmap 是 jdk 工具链的其中一个。一般情况下,需要debug的服务,运行的 jdk 是哪个版本就用该版本下的工具链,例如,是java 1.8.0 jdk就用 1.8.0的 。
2、安装 MAT
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
根据各自的桌面系统选择不同的版本,配置好java sdk bin 环境变量就可以直接打开使用。
下载地址:https://www.eclipse.org/mat/downloads.php
使用配置
1、获取 es 的主进程号
[liuzexu@gz-52-175 ~]$ systemctl status elasticsearch
● elasticsearch.service - Elasticsearch
Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/elasticsearch.service.d
└─override.conf
Active: active (running) since 三 2018-09-12 02:08:28 CST; 1 day 9h ago
Docs: http://www.elastic.co
Main PID: 144765 (java)
CGroup: /system.slice/elasticsearch.service
└─144765 /bin/java -Xms31g -Xmx31g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingO...
9月 12 02:08:28 gz-52-175 systemd[1]: Started Elasticsearch.
9月 12 02:08:28 gz-52-175 systemd[1]: Starting Elasticsearch...
其中Main PID: 144765 (java)
的 144765
就是主进程号。
2、使用 jmap
以二进制的方式输出,输出到/tmp/es-heap.hprof
,其中 {PID}
改为 144765
就可以
sudo -u elasticsearch jmap -dump:format=b,file=/tmp/es-heap.hprof {PID}
输出hprof
过程中,会让当前的 es 进程保持在阻塞状态不再工作,请务必在不影响业务的时间内进行,例如深夜。
假设输出hprof
为22G的大小,一般需要花费了1分钟。
3、使用 MAT
如果es-heap.hprof
大于1G,需要更改 MAT 的配置去支持大文件的读取。不同环境的 MAT 的配置方式不一样,下面是 Windows x64 版本的 Eclipse Memory Analyzer 的例子。
在软件目录下,打开编辑MemoryAnalyzer.ini
,找到-Xmx1024M
,改为hprof
大小,就可以了,例如hprof
20G,改为-Xmx20g
。改完保存即可。重新启动 MAT,就可以顺利打开hprof
。
下面是打开后的例子:
example |
---|
然后就可以愉快地查看 heap 的各种情况了。
教程至此。
本文由 Chakhsu Lau 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。