一次导入大文件导致的oom问题的排查与排查工具的分享
前言:
关于OOM问题的排查,说实话在这之前并没有这方面的经验,于是去百度借鉴了一番,瞄准了JVM内存可视化分析的工具jvisualvm.exe(jdk自带)与和他配套使用的基于idea的插件VisualVM Launcher.
背景:
某功能一次性读取好几百M的文件数据,并导入到数据库. 查看后台日志和代码发现在导入过程中使用了一个list读取文件内所有数据后再提交DataBase过程中发生了OOM.
准备:
1.jvisualvm.exe 该工具jdk自带 JAVA_HOME/bin/jvisualvm.exe
2.idea插件VisualVM Launcher(安装与配置详见img_idea_vm_*.png)

img_idea_vm_01.png

img_idea_vm_02.png
1 | img_idea_vm_02.png 中 |
模拟复现代码:
模拟读取数据一直往list里面存储文件数据,最后导致OOM.(这里需要给main方法的启动类配置VM参数 -Xmx100m -Xms20m)
1 | public static void main(String[] args) { |
在run()方法里面循环的地方打一个断点,以方便我们启动内存分析工具进行分析(避免还没运行内存分析工具程序就执行完了…),然后我们以debugger以及jvisualvm启动代码


OOM异常信息:
1 | ... |
jvisualvm启动后可以很快就看到OLD区域的内存被很快打满,同时也一直在GC.
当我用了jvisualvm这个工具不得不感叹,这工具真是太香了,尤其是在你处理OOM异常的时候,可以很清晰的看到内存的状态.有了这些工具+debugger代码排查起来问题将会非常方便.
解决方案:
找到了问题,那么就可以根据循环读取数据的过程做一个分批提交,然后及时的清除list所占用的内存,这样就解决了内存被撑爆的OOM问题.
解决代码:
1 | if(lists.size() > 5000){ |
作者: K