Record a production environment OOM

Suddenly frequently hang up the production environment, see the error log OOM

Look can not determine the cause of the log, thus trying to analyze memory dump down

First, let's take a look at startup.sh tomcat startup script in the bin directory of tomcat (version here is tomcat8.5)

Will start the process to execute catalina.sh, the following is part of catalina.sh

If setenv.sh script exists, tomcat will start to execute the script, here it is suitable for adding custom parameters

vim setenv.sh create this file

写入:JAVA_OPTS="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Xmx6144m -Xms6144m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/www/server/tomcat/oom_dump"

esc-->:-->wq

-Dfile.encoding: Specifies the content of the document encoding format

Encoding format specified file name: -Dsun.jnu.encoding

-Xmx6144m: Set JVM maximum memory available to 6114M

-Xms6144m: Set initial JVM memory size 6114M

ps: this server is memory 8G, 6G is assigned to the JVM, nearing their limits.

-XX: + HeapDumpOnOutOfMemoryError: save a snapshot in the event of OOM

-XX: HeapDumpPath = / www / server / tomcat / oom_dump ": Snapshot Save address" / www / server / tomcat / oom_dump "

ps: Here we must confirm tomcat has permission to modify the folder, such as I have here is to start with www user tomcat, I created a root user login server / www / server / tomcat / oom_dump folder, the default permissions are need root privileges to access, setenv.sh file still have to pay attention to rights issues.

命令groups [用户名] 可以查询用户所属的组,直接输入groups是查询当前登录用户的组

修改文件夹所属的组和用户,使用命令:

chown 用户名:组名 文件夹名/文件名

chown  www:www  /www/server/tomcat/oom_dump

chown  www:www  /www/server/tomcat/bin/setenv.sh

用户名没有冲突的话也可以直接使用chown  www  /www/server/tomcat/oom_dump

果不其然再次OOM。。T_T

找到/www/server/tomcat/oom_dump/java_pid12907.hprof

下载下来,然后推荐使用eclipse的MemoryAnalyzer(MAT)来分析,简单好用

打开eclipse-->help-->Eclipse Marketplace,搜索MemoryAnalyzer-->Install

MAT教程:https://www.cnblogs.com/UncleYong/p/7743294.html#MySignature

ps:依据快照文件大小可能需要调整eclipse的配置

打开eclipse安装目录-->找到eclipse.ini-->编辑,将-Xmx调大,我的快照文件是1.5G,我这里调大至-Xmx4096m,eclipse的JVM内存小于快照文件大小会导致打不开。

打开MAT面板

 

 

 

 Open Heap Dump -->选择快照文件会得到如下视图:

 

 

 

1.Histogram可以列出内存中的对象,对象的个数以及大小。

2. Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
3.Top consumers通过图形列出最大的object。
4.Leak Suspects通过MA自动分析泄漏的原因。

点击Dominator Tree

 这里我点开最大占用的对象

 发现是嵌套ArrayList,里面全是字符串,占用了将近700M(原本服务器设置的最大堆内存为2G)

最终找到了引发OOM的类,查找到了原因,业务是加载oss上的文件,读取文件内容存入List再转成json返回给前端,但是该文件太大了。

修改接口为只返回文件路径给前端,点击查看才尝试加载文件,如果大小超过2M则提示不支持预览,请下载后查看。

另外Leak Suspects-->Details-->See stacktrace也能定位到问题发生的位置。

 

 本文有不当之处还请各位看官不吝赐教,感谢查看。

Guess you like

Origin www.cnblogs.com/zou-rong/p/11952825.html