目前项目中用到的是sturts1.x+spring2.0.7+hibernate3,Web部分Struts Action通过Spring托管,为了在进入Action方法之前,需要执行一些权限的判断之类的方法,故使用Spring 针对所有Action的方法进行BeanNameAutoProxyCreator AOP代理,由于Action没有实现接口,故该AOP是使用CGLIB代理的,CGLIB版本为2.1.3,这样问题就来了:问题重现前提:
屏蔽后台代码,只有web部分的代码.1:当Struts Action bean设置为singleton="false"时,在WEB页面不断挨个点击菜单链接,每个菜单链接都是通过Action跳转的,也就是不停的会触发该cglib代理,用jconsole监控,发 现类加载的数量不断上升,perm gen区也不断上升,一个小时之后,perm gen溢出2:当Struts Action bean设置为singleton="true"时,做相同的操作,就缓解了这种现象,跑了1-2天也就上升的不多,但总体来说是上升的.google了一把,说是cglib创建代理类的时候,需要重写实现了CallbackFilter接口实现类的equals和hashCode方法,修改为
始终创建一个代理类,但是这个实现类是在Spring源码里面的,我修改了,但是没效果,我想也不可能,Spring使用了这么久,怎么没见人提到这个bug.这是什么原因,cglib代理会造成内存泄露吗,和是否单例有什么关系?
难道cglib会针对非单例的类不断的去创建代理类放到perm gen区吗,那Action岂就不能为多例模式了,
为什么cglib还有这么多人用求解!

解决方案 »

  1.   

    具体我也没有深入研究。只谈下看法。
    如果将action配置为singleton,每次请求都生成一个新的实例这是肯定的。但是permgen space的内存溢出应该一般都是在spring采用cglib生成动态代理时,生成的class太多而导致系统分配的内存不够大导致的。
    楼主最后一段话我的看法是,会创建代理类,然后又classloader动态装载。但一个action生成多少个代理类应该是根据整个系统代码(包括struts、spring中)被代理多少次决定,这个代理类的个数应该是一定的。
    只不过对应的这个代理类对应N个并发线程能产生多个实例而已。按此来想,应该不可能是这个原因导致内存溢出。