记一次使用Memory Analyzer工具分析堆内存溢出问题
Posted 柚子聊大数据
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次使用Memory Analyzer工具分析堆内存溢出问题相关的知识,希望对你有一定的参考价值。
为了低耦合的处理HDFS上存储的各种格式文件,如Parquet、Orc、Csv、Txt等,我司的大数据平台封装出了两类算子:
将需要处理文件的全路径用集合来存放,并转换成Dataset,最终以Spark 临时表的形式输出,传递给下一个算子。(前置与后置算子之间,通过Spark临时表串联起来)
处理具体文件格式的算子,如Parquet文件则会使用org.apache.spark.sql.parquet.DefaultSource来处理。
某项目使用这两类算子去接入HDFS上的Parquet文件时,Spark Driver端经常会出现OOM现象。那么问题来了,Driver 端Heap到底有哪些大对象?
说明:
我司Spark版本是2.3.1,所有任务均以Yarn Client方式提交到Yarn集群。
Eclipse Memory Analyzer是一款Java堆分析器,可用来快速的定位内存泄漏问题,其官网见链接1。从下图中可以看出,MAT提供了两种运行方式,一种是作为Eclipse的插件运行,另一种独立于eclipse运行。
其实JDK也自带了一个jconsole,它也可以打开dump文件,从而分析内存泄漏问题。那MAT的优势在哪?
1、 在本次生产环境中,-Xms、-Xmx均设置为40G,OOM时生成的dump文件在我司的办公PC机上(linux上的jconsole就没有用过咯o(╯□╰)o),用jconsole压根打不开(内存不够)。
2、 MAT提供的ParseHeapDump脚本,可对dump文件进行分析,并给出一个分析报告结果,根据该分析报告(该报告就几百KB),可以更简单的定位出问题所在。
3、 现场40G的dump文件,如何传回公司,也是一个头疼的问题。
1、解压
unzip MemoryAnalyzer-1.8.1.20180910-linux.gtk.x86_64.zip
2、根据dump文件的大小,修改MAT Heap大小
修改MemoryAnalyzer.ini文件中的-Xmx值即可
3、运行如下命令,得到分析结果
nohup ./ParseHeapDump.sh /home/zsf/mat/zsf.hprof
org.eclipse.mat.api:suspects org.eclipse.mat.api:overview
org.eclipse.mat.api:top_components &
执行结果:
zsf_Leak_Suspects.zip
zsf_System_Overview.zip
zsf_Top_Components.zip
4、查看分析结果
解压zsf_Leak_Suspects.zip,打开index.html文件,首页如下
从该图中可以发现,FileStatus数据占用了90%的堆大小。此时点击“See stacktrace”查看具体的调用堆栈。(介于此处涉及公司的代码,此处就不贴代码截图了)
最终,发现FileStatus[] 对象出自如下代码
FileStatus[] status = fs.listStatus(p);
1、改用Iterator的方式来获取FileStatus对象
RemoteIterator<FileStatus> statusIterator = fs.listStatusIterator(p);
2、重启应用,生成dump文件,并分析dump文件
获取dump文件的命令如下:
jmap -dump:format=b,file=zsf.hprof 123102
zsf.hprof为dump文件名称,123102为进程号。
当命令执行成功后,会在当前目录生成一个zsf.hprof文件。
重新用MAT对dump文件进行分析,生成结果后,解压zsf_Leak_Suspects.zip,并打开index.html,如下图所示:
经过两次index.html内容的对比,可以发现修改代码后已起作用,FileStatus数组对象已不会占用太多内存。
1、https://www.eclipse.org/mat/downloads.php
温馨提示
以上是关于记一次使用Memory Analyzer工具分析堆内存溢出问题的主要内容,如果未能解决你的问题,请参考以下文章
Eclipse MAT内存分析工具(Memory Analyzer Tool)
eclipse安装memory analyzer工具分析堆转储信息
Java堆分析器 - Eclipse Memory Analyzer Tool(MAT)
Java堆分析器 - Eclipse Memory Analyzer Tool(MAT)