项目新上的功能,批量扫描excel文件,读取数据整理并存库。在最后的性能测试的时候发现大数据量文件总是出现OOM,业务线程中断并生成dump文件。
首先JVM参数
-Xmx1024m -Xms1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:AutoBoxCacheMax=20000 -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/home/logs/gc.log
UseG1是第一次发现OOM后加上的
从服务器导出dump文件到本地
使用MAT(Eclipse Memory Analyzer)工具打开此文件
如果没有安装可以下载 下载地址: Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation
我这里用的Java8,下载的版本是 Memory Analyzer 1.9.2 Release
解压后双击exe文件即可
ini文件里可以修改内存
在工具首页点击open 选择hprof文件
在加载完文件后点击 leak suspects,我这里是自动弹出的
可以看到分析结果显示有个线程池占用了大部分的内存,点击see stacktrace可以看到线程栈的详细信息
点击上方按钮,展示占用内存的对象列表,在最占用内存的对象上右键查看详细内容
展开前几个查看value内容可以看到,开发人员习惯性把数据输出到log日志当中导致占用了大量的内存
根据上面的信息找到代码的类方法去优化。
总结:log信息输出大量数据可以打印集合的条数,不要把集合详细信息输出,否则在大数据量跑批情况下会占满堆内存。