tomcat5.5 reload 出现方法区溢出的问题

        最近在用eclipse调试一个老项目,server用的tomcat5.5, reload了几次应用就报错,方法区溢出:

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space。

用visualvm查看heap dump,发现项目中的第三方jar包的类都被重新加载了好几次,最后方法区空间不足,一直进行fullgc,却无法回收重复的类。
  用tomcat7相同环境下运行正常,reload几次后,方法区空间不足时,会回收所有原先WebappClassLoader重复加载的类,
2个tomcat jvm运行模式和参数都一致,都是使用默认的垃圾回收机制,后来tomcat5.5试着用了CMS垃圾收集器还是报原先的错误:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
应该是tomcat5.5 reload代码实现有问题
tomcat7的reload源码,应该tomcat7在reload时清理引用做了写改进吧,WebappClassLoader处理内存泄露 clearReferences():
    /**
     * Clear references.
     */
    protected void clearReferences() {

        // De-register any remaining JDBC drivers
        clearReferencesJdbc();

        // Stop any threads the web application started
        clearReferencesThreads();

        // Check for leaks triggered by ThreadLocals loaded by this class loader
        checkThreadLocalsForLeaks();

        // Clear RMI Targets loaded by this class loader
        clearReferencesRmiTargets();

        // Null out any static or final fields from loaded classes,
        // as a workaround for apparent garbage collection bugs
        if (clearReferencesStatic) {
            clearReferencesStaticFinal();
        }

         // Clear the IntrospectionUtils cache.
        IntrospectionUtils.clear();

        // Clear the classloader reference in common-logging
        if (clearReferencesLogFactoryRelease) {
            org.apache.juli.logging.LogFactory.release(this);
        }

        // Clear the resource bundle cache
        // This shouldn't be necessary, the cache uses weak references but
        // it has caused leaks. Oddly, using the leak detection code in
        // standard host allows the class loader to be GC'd. This has been seen
        // on Sun but not IBM JREs. Maybe a bug in Sun's GC impl?
        clearReferencesResourceBundles();

        // Clear the classloader reference in the VM's bean introspector
        java.beans.Introspector.flushCaches();

    }
查了相关的资料:
 一般程序库可能存在内存泄漏的地方有:
 1.JDBC驱动注册
2.一些日志框架
3.在ThreadLocal中保存对象,但是并不去删除它 
4.启动了线程,但没有停止它 
而Java API存在内存泄漏的地方包括:
1.使用javax.imageio API (the Google Web Toolkit can trigger this) 
2.使用java.beans.Introspector.flushCaches() (Tomcat does this to prevent memory leaks caused by this caching) 
3.使用XML解析器(the root cause is unknown due to a bug in the JRE) 
4.使用RMI远程方法调用(somewhat ironically, causes a leak related to the garbage collector)  
 5.从Jar文件中读取资源




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值