记一次JVM内存溢出的处理过程-创新互联
概要
笔者所管理的测试一台业务服务器,近期经常被反馈应用卡顿并且出现过多次内存溢出,本篇为对此问题的处理过程的记录。
服务器环境采用Oracle JDK1.6,虚拟机为HosSpot,Web容器为Tomcat7。
处理过程
获取堆内存转储快照
在用户反馈系统卡顿时,登陆服务器通过命令查看内存使用情况
创新互联服务项目包括武昌网站建设、武昌网站制作、武昌网页制作以及武昌网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,武昌网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到武昌省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
jps #获取java的进程ID
jstat -gc 31795 #31795为jps查询到的进程ID
得到内存使用情况如下:
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
932032.0 932032.0 0.0 0.0 932096.0 932096.0 5592448.0 5592448.0 131072.0 60017.9 20 13.991 69 892.270 906.260
从结果可以得知,堆内存已经达到容量上限,并且在不断的进行FGC,所以应用系统表现的特别卡顿。
通过jmap命令生成堆转储快照:
jmap -dump:format=b,file=heap.hprof 31795
出现以下提示则表示生成成功:
Attaching to process ID 31795, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.45-b01
Dumping heap to heap.hprof ...
Heap dump file created
分析堆转储快照
使用MemoryAnalyzer打开堆转储快照,但提示heap space的堆内存溢出的异常:
An internal error occurred during: "Parsing heap dump from 'java_pid4259.hprof'".
Java heap space
修改配置MemoryAnalyzer.ini,调整堆内存大小
-Xms1024m
-Xmx8192m
在MAT的Leak Suspects中,可以看到很详细的信息,有两个对象占用了大量的内存。
通过查看线程信息发现为一个报表功能,该报表查询的数据量太大,而且sql效率比较低。
优化思路
- 限制报表提取条件,尽量控制报表的大小在合理范围内
- 超大的报表采用其他实现方式,例如通过定时任务将报表生成存放在指定文件服务器,由用户自行下载
- 本例中的报表会由jdbc的ResultSet 转成最终的报表对象,中间会经历很多中间步骤,例如Vetcory、ArrayList等,尽量减少中间步骤
- 优化sql,尽快释放对象,可以被GC进行回收
分享文章:记一次JVM内存溢出的处理过程-创新互联
浏览地址:http://scgulin.cn/article/ceeccs.html