一次Java内存泄露处理手记
现象
最近项目组从NET平台迁移到Java的Dubbo平台上,由于大家都是Java的生手,发生了蛮多的问题,以后一一记录。现在解决一个遇到的关于Java程序内存泄露的问题。
特别说明
Java萌新,理解不到位的地方请指点一二
版本
- Java 1.8
- Dubbo 2.6.2
- Docker 18.0.2
系统环境
我们这里是Docker Swarm集群,三台机器组成,Dubbo服务随机部署到三台机器上。
问题重现
上线了一个Dubbo服务,这个服务涉及到数据库查询、排序分析、第三方接口调用。
服务启动初始内存占用500MB左右,每检索一次,内存增加10MB到几十MB不等,而且不释放。持续增高,最高可以塞满整个服务器的内存。
检查问题
首先,由于我们是部署在Docker集群上的,所以得去容器内进行检查,刚上线,所以基础容器选择的是JDK版本,没有用JRE。因为JDK带有很多的调试工具。
查看生产环境并导出heap.hprof
首先看看容器的运行情况:
docker stats
这是后面调试的时候截的图,早期发现的时候,内存是4.8G。明显内存占用过多了。
因为宿主是没有任何java环境的,进容器内做内存分析。
docker exec -it 容器ID bash # 进入指定容器
jmap -histo 1 | head -n 30 # 通过jmap工具查看
jmap的检查结果当时忘了截图了,这里就不留存了,百度能搜到了,就一笔带过。
现在导出heap.hprof
文件,方便用MAT
进行分析。
jmap -dump:format=b,file=heap.hprof 1
在docker容器内,PID 1 是服务进程,以上命令将会在当前目录生成heap.hprof
文件,比较大,我的有1.2G。可以先压缩了,再传回来,进行分析。
使用MAT进行内存分析
独立版下载地址:MAT
打开从服务器下载回来的heap.hprof
文件
点击Leak Suspects
查看分析结果。
点击Details
查看详情
上图可以看到,MAT分析结果表明,OcMapperFactory这个类有问题。
看看具体代码:
这个OcMapperFactory
是用来封装orika
的工具类,而orika
是一个对象映射工具。由于这里没有用单例导致了内存的泄露。加上单例再看看:
重新测试,发现内存已经稳定。
作者:Li keli
出处:https://www.cnblogs.com/likeli/p/9413830.html
本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?