最近在用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垃圾收集器还是报原先的错误:
应该是tomcat5.5 reload代码实现有问题
                用tomcat7相同环境下运行正常,reload几次后,方法区空间不足时,会回收所有原先WebappClassLoader重复加载的类,
2个tomcat jvm运行模式和参数都一致,都是使用默认的垃圾回收机制,后来tomcat5.5试着用了CMS垃圾收集器还是报原先的错误:
-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled应该是tomcat5.5 reload代码实现有问题
 tomcat7的reload源码,应该tomcat7在reload时清理引用做了写改进吧,WebappClassLoader处理内存泄露 clearReferences():
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文件中读取资源
 
                   
                   
                   
                   
                             
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   6万+
					6万+
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            