今天上午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:應該說是我們已知的所有問題都已經得到解決,可能還存在一些未知的問題。
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,你還有什麼其他要補充的嗎?