一个spark streaming应用executor所耗内存随着时间的增长一直在增加,直到executor内存不足导致应用异常终止,单从代码层面上还无法定位到内存泄漏的位置。因此可通过监控executor进程内存,获取内存变化情况。这里使用java自带的jmc(java mission control)工具来监控进程。
环境信息:
JDK:1.8
Spark:2.3.2
Windows:win10
Eclipse: Oxygen.1a Release (4.7.1a)
MAT:1.9.2
需要添加的参数如下:
-Dcom.sun.management.jmxremote.port=7091 //开启远程连接的端口
-Dcom.sun.management.jmxremote.authenticate=false //是否开启验证,改为false
-Dcom.sun.management.jmxremote.ssl=false //是否使用ssl加密协议
如果需要参看飞行记录器,还需要添加如下参数:
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
spark配置方式如下几种:
1.安装MAT插件
打开Eclipse,“Help”-》“Eclipse Marketplace”,Find一栏搜索"MAT",安装“Memory Analyzer xxx”,选择安装项时将optional选项也选中,安装完成后重启Eclipse。
2.**MAT插件
“Window”-》“Perspective”-》“Open Perspective”-》“Other…”-》“Memory Analysis”点击open,打开mat插件。
1.使用jmap命令获取内存泄漏的executor进程的thread dump
jmap -dump:format=b,file=xxx.hprof
其中“pid”为executor对应的进程号
2.使用MAT打开Dump文件
打开Eclipse,“File”-》“Open Heap Dump…”,打开下载的dump文件xxx.hprof,选中“Leak Suspects Report”点击“Finish”,加载Dump文件
展示出的结果为内存占用统计,可看到其中一个占用比列远远超过其他部分,达612.3MB
点击饼状图,进入详情
可看到TaskQueue队列类的一个实例比例超高,点击“See stacktrace”查看堆栈详情,看到时redis相关实例占用较大内存,确定是redis代码侧导致内存泄漏。调整相关代码后内存泄漏恢复。