【译】关于 “Tomcat 7 内存泄漏保护” 的访谈

鉴客 发布于 2010/06/09 13:13
阅读 1K+
收藏 1

今年年初,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引用的对象还在,这样就会导致内存泄漏。

一般程序库可能存在内存泄漏的地方有:

  • JDBC 驱动注册
  • 一些日志框架
  • 在 ThreadLocal 中保存对象,但是并不去删除它
  • 启动了线程,但没有停止它

而 Java API 存在内存泄漏的地方包括:

  • 使用 javax.imageio API (the Google Web Toolkit can trigger this)
  • 使用 java.beans.Introspector.flushCaches() (Tomcat does this to prevent memory leaks caused by this caching)
  • 使用 XML 解析器 (the root cause is unknown due to a bug in the JRE)
  • 使用 RMI 远程方法调用(somewhat ironically, causes a leak related to the garbage collector)
  • 从 Jar 文件中读取资源

DZone:请告诉我们,Tomcat 7 是如何处理这些问题的

Mark Thomas:问题的关键在于 Tomcat 7 的 WebappClassLoader 类的 clearReferences() 方法。

对于前面提到的 Java API 中存在问题,通过确保 Tomcat 核心第一次使用这些 API ,然后让应用去调用,来防止内存泄漏。关于如何保护内存泄漏,请看 JreLeakPreventionListener class.

译者注:关于 Tomcat 7 停止时的资源释放问题请看:http://www.oschina.net/bbs/thread/8794

DZone:依你看来,在控制内存泄漏方面,Tomcat 7 比现有版本的 Tomcat 有多大的提升?

Mark Thomas:有显著的提升,呵呵

DZone: Tomcat 7 的开发进展如何,有一个确切的发布日期吗?

Mark Thomas:Tomcat 7 的开发进展非常顺利,JSP 和 EL 2.2 规范已经实现,Servlet 3.0 的规范实现也接近完成。

DZone:关于 Tomcat 7 ,你还有什么其他要补充的吗?

Mark Thomas:Tomcat 7 在嵌入式方面同样做了很多改进,比以往的任何一个版本,更加适合嵌入。另外 Tomcat 社区一直在寻找新贡献者,希望能有更多的人加入 Tomcat 的开发。

查看原文:http://java.dzone.com/articles/memory-leak-protection-tomcat

加载中
0
JavaGG
JavaGG

如果可以防止年老代泄漏就牛B了

0
张林
张林

我弄明白了,归根结底就不是tomcat的bug,是javaAPI的一个bug PermGen。Tomcat只不过改变了一下调用策略,本来是核心调用的现在让应用去调用。

0
胖猫
胖猫

shit,我还真遇到这个bug了

0
钛元素
钛元素

我每天都为这个bug烦恼

0
jobar
jobar

原来用ThreadLocal,也会产生内存泄漏啊。。我也碰到过这个bug

返回顶部
顶部