今天上午51CTO为网友第一时间对“Tomcat 7 RC4发布”进行了报道。Tomcat 7的内存泄漏保护一直是关注,今年年初,DZone网站对Mark Thomas针对Tomcat 7的内存泄漏保护的功能进行了采访,Mark Thomas是SpringSource的首席软件工程师,同时也是Tomcat的代码提交负责人。
在Tomcat 7中引入了一项新的功能:内存泄漏保护。该功能可以解决Web应用中的很多种会导致内存泄漏的问题,特别是在应用重新加载时候的内存释放问题。
下面是具体访谈的内容(水平有限,对内容做了很多精简,详情请看英文版):
DZone:什么原因会导致Web应用重新加载时的内存泄漏,这个内存泄漏是怎么表现出来的?
Mark Thomas:最直接的现象就是PermGen产生OutOfMemoryError的错误,然后Tomcat挂掉
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,如果你的WEB APP下都用了大量的第三方jar,其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
为了防止该问题的发生,必须保证重载时web应用的类加载器没有保存任何对象的引用。
DZone:请告诉我们Tomcat以前在重载时的内存泄漏问题
Mark Thomas:Tomcat的这个问题在我加入这个项目之前就一直都存在
DZone:那么是不是所有Tomcat中会导致内存泄漏问题的Bug都已经修复了呢?
Mark Thomas:应该说是我们已知的所有问题都已经得到解决,可能还存在一些未知的问题。
Tomcat 的虚拟机内存剖析
DZone:程序库、Java API都有什么用的bug会导致内存泄漏呢?
Mark Thomas:内存泄漏问题都有相同的原因,例如在Web应用的ClassLoader初始化一个对象,然后这个对象将自己的引用保存到某个实例或者Registry中,当重载时从ClassLoader撤销这个对象时,Registry引用的对象还在,这样就会导致内存泄漏。
一般程序库可能存在内存泄漏的地方有:
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文件中读取资源
DZone:请告诉我们,Tomcat 7是如何处理这些问题的
Mark Thomas:问题的关键在于Tomcat 7的WebappClassLoader类的clearReferences()方法。
对于前面提到的Java API中存在问题,通过确保Tomcat核心第一次使用这些API,然后让应用去调用,来防止内存泄漏。关于如何保护内存泄漏,请看JreLeakPreventionListener class.
DZone:依你看来,在控制内存泄漏方面,Tomcat 7比现有版本的Tomcat有多大的提升?
Mark Thomas:有显著的提升,呵呵
DZone:Tomcat 7的开发进展如何,有一个确切的发布日期吗?
Mark Thomas:Tomcat 7的开发进展非常顺利,JSP和EL 2.2规范已经实现,Servlet 3.0的规范实现也接近完成。
DZone:关于Tomcat 7,你还有什么其他要补充的吗?
【编辑推荐】