内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。
- 通常测试环境数据量小,可能发现不了问题,发到生产后问题可能就暴露出来了。导过一次生产环境的数据,在测试环境跑,内存直接溢出了,原因一个是测试环境配置低、另一个就是数据量大。后来使用分页和缓存得以解决
- 还有一次是导出图片,往压缩包中写入的图片太多,内存溢出了。做了数量限制解决
引起内存溢出的原因有很多种,常见的有以下几种:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.启动参数内存值设定的过小;
经历几次,总结了两种方式下载dump文件,根据实际场景分析排查问题
1. 自动下载
2. 手动下载
第一种方式是一种后置动作,只有等当前JVM出现问题后才会触发生成dump文件
第二种方式可以立刻手工生成,但在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。
一、自动下载
加启动参数
-
-XX:+HeapDumpOnOutOfMemoryError #参数表示当JVM发生OOM时,自动生成DUMP文件。 看情况选择-XX:+HeapDumpBeforeFullGC
-
-XX:HeapDumpPath=/tmp/heap.hprof #生成路径
二、手动下载
- cd /home/admin/logs
2. 切换用户角色,不然可能无法执行后面的命令
su admin
- 查看当前所有 java 进程的 pid
- 将当前Java进程的内存占用情况导出来 (jmap 是一款Java内存映像工具,可以尝试一下常用命令)
jmap -dump:format=b,file=/tmp/heap.hprof 21306
- 如下便创建了dump文件,下载到本地即可
没有限制直接下载; 有限制,注意:堡垒机下载文件到上限大概是2G,直接下载有限制,快点方式,移到/temp 下,利用ftp工具下载到本地
- mat、JProfile 、idea、 Jdk bin目录下的jvisualvm.exe 都可以去分析
三、young gc
使用mat分析排查 java程序cpu一直很高,young gc频繁问题
young gc意味着unreachable objects产生和销毁速度很快,一般导致unreachable objects产生快的原因是数据库里拉取的数量多和快,因此主要关注list和map,找到对应的list和map的类对象,联系最近的代码,有没有修改批量拉取的数量和频率,大致就能找到问题。