使用 MAT 排查 JVM内存溢出

现象:近半年来,服务器约每月一次内存溢出,之前没有过。

一、加大JVM内存:失败;原因:32位JDK最大只能支持1024M。

试图通过加大内存解决,发现原jvm参数是:xmx=xms=1024M,PermSize=256,MaxPermSize=512,xmn=256

改为xmx=xms=2048M,PermSize=512,MaxPermSize=1024,xmn=512后,启动时报错:

Error occurred during initialization of VM  

Could not reserve enough space for object heap

百度获知32位jdk最大支持1.4-1.6G,于是明确了一下服务器运行环境:
                                       

OS  Windows Server  2003(32位)
CPU 双核
内存 8G
APP SERVER Oracle Weblogic11gR1
JDK JDK 1.6_45(32位)

确实是32位,尝试设置为1G<xmx<1.5的值,发现大于1024就启动不了,方法失败。

二、尝试检查是否有内存泄露点:

1、用jvisualVM查看,虽然未进行详细的抽样记录,但是观察发现:

应用刚启动时:堆内存最大使用量<500M,服务器自动每5分钟GC一次,GC后堆内存变250M,

半天后:堆内存最大使用近750M,服务器自动每4分钟GC一次,GC后堆内存变500M

一天后:堆内存最大使用近1000M,服务器自动每3分钟GC一次,GC后堆内存大约800M左右

推测确实有内存溢出点

       尝试用jvisualVM的抽样器和Profiler,结果服务器被搞挂了……

2、问了公司架构组的大牛,他建议我用MAT

       于是又研究了半天MAT,找到了几篇使用MAT分析内存泄露的文章,最后一篇:http://m.blog.csdn.net/blog/s464036801/20712809,让我定位到了内存泄露点。
 

发现cglib生成了InitProcessService类的4000多个代理类,占用了约67.89%的空间。所以InitProcessService的每次调用都生成了一个代理类。cglib是可以以key-value方式缓存其生成的代理类的类定义对象的,其中key是通过被代理的类的类信息等生成的,value即为生成的代理类的类定义对象,这样就不需要每次调用都生成一个新的代理类,否则的话内存很容易就OOM了。但是否缓存是可以设置的,默认开启缓存,可以通过方法关闭缓存。于是检查我的应用,确认缓存是开启的。

最后发现spring bean定义文件中InitProcessService类的scope="prototype",设为默认后再通过jvisualVM查看,这个类的cglib生成的代理类的类定义对象就始终只有一个了。

这很让我疑惑,因为cglib生成的代理类的类定义对象应该是与spring 中被代理的bean 的scope属性无关的,因为scope属性是指定类实例的管理方式,而非类定义对象的管理方式。

待解……

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值