现在系统的日志功能,我通过cglib实现AOP来实现的,一开始都很正常,可是跑了没一天就报out of memory:Perm Gen,google了一下说Perm Gen是永久内存区域,专门存放class meta的.一开始不明白为什么光存放class为什么会导致Perm Gen溢出,后来测试发现cglib实现的代理类,每new一个代理类,Perm Gen都会增加,我晕啊.
疑问:
1. 为什么new一个代理类,Perm Gen都会增加,不是说Perm Gen里每个class只保留一份吗?难道说代理类生成对象时所使用的class都是不同的(我发现代理类生成的class都类似OutboundNoticeBiz$$EnhancerByCGLIB$$b812b06c,猜测是不是同一个代理类生成的class,后面$$b812b06c都不一样),这样就能理解为什么new一个代理类,Perm Gen都会增加,因为他们的class不同.那这样溢出就是必然的了.
2. 现在Hibernate也是使用cglib实现AOP的,那使用Hibernate框架的系统,一段时间后难道也会class数量越来越多,最后out of memory:Perm Gen了,不解.如果真是这样,那Hibernate不是很失败,为什么还有那么多系统使用呢.还是说Hibernate有什么办法解决了这个问题.
我的环境是SUN JDK 5.0, 操作系统WINDOWS XP, cglib-2.1_3.jar(最新版本,听说之前的版本会导致out of memory,但不是Perm Gen的这种)
也有人提议使用IBM JDK或者JRockit JDK,他们没有Perm Gen,有自己的class storage (Non-heap memory),这个区域是不属于java heap的,后来我换了JRockit试试,发现java heap到时没增加,可是我的物理内存在不停的被吃掉,而且没有释放的意思,越来越大,最后我的本本内存耗光假死在那了,最后只能把JBOSS强关.所以换其他JDK还是没有根本解决问题,CLASS数量越来越多,而且也不会被释放.郁闷呐!!!
疑问:
1. 为什么new一个代理类,Perm Gen都会增加,不是说Perm Gen里每个class只保留一份吗?难道说代理类生成对象时所使用的class都是不同的(我发现代理类生成的class都类似OutboundNoticeBiz$$EnhancerByCGLIB$$b812b06c,猜测是不是同一个代理类生成的class,后面$$b812b06c都不一样),这样就能理解为什么new一个代理类,Perm Gen都会增加,因为他们的class不同.那这样溢出就是必然的了.
2. 现在Hibernate也是使用cglib实现AOP的,那使用Hibernate框架的系统,一段时间后难道也会class数量越来越多,最后out of memory:Perm Gen了,不解.如果真是这样,那Hibernate不是很失败,为什么还有那么多系统使用呢.还是说Hibernate有什么办法解决了这个问题.
我的环境是SUN JDK 5.0, 操作系统WINDOWS XP, cglib-2.1_3.jar(最新版本,听说之前的版本会导致out of memory,但不是Perm Gen的这种)
也有人提议使用IBM JDK或者JRockit JDK,他们没有Perm Gen,有自己的class storage (Non-heap memory),这个区域是不属于java heap的,后来我换了JRockit试试,发现java heap到时没增加,可是我的物理内存在不停的被吃掉,而且没有释放的意思,越来越大,最后我的本本内存耗光假死在那了,最后只能把JBOSS强关.所以换其他JDK还是没有根本解决问题,CLASS数量越来越多,而且也不会被释放.郁闷呐!!!
望知道的帮帮我,这个问题已经从春节缠我到现在了,谢谢.
答案在这里:
自己找到原因了,知道怎么让cglib每次都生成相同的class了,和大家分享一下.
就是将实现CallbackFilter的类,也实现equals()和hashCode()方法,这个类的这两个方法与cglib内部的class cache的key相关.
还有一个就是把cglib.jar包升级为最高版本~2.1版本有个bug,会导致内存溢出