Tomcat 檢測(cè)內(nèi)存泄漏實(shí)例詳解
Tomcat如何檢測(cè)內(nèi)存泄漏
一般情況下,如果我們重啟web應(yīng)用是通過(guò)重啟tomcat的話,則不存在內(nèi)存泄漏問(wèn)題。但如果不重啟tomcat而對(duì)web應(yīng)用進(jìn)行重加載則可能會(huì)導(dǎo)致內(nèi)存泄漏,因?yàn)橹丶虞d后有可能會(huì)導(dǎo)致原來(lái)的某些內(nèi)存無(wú)法讓GC回收,例如web應(yīng)用使用了JDBC,驅(qū)動(dòng)會(huì)進(jìn)行注冊(cè),當(dāng)web應(yīng)用停止時(shí)沒(méi)有反注冊(cè)就會(huì)導(dǎo)致內(nèi)存泄漏。
看看是什么原因?qū)е聇omcat內(nèi)存泄漏的。這個(gè)要從熱部署開始說(shuō)起,因?yàn)閠omcat提供了不必重啟容器而只需重啟web應(yīng)用以達(dá)到熱部署的功能,其實(shí)現(xiàn)是通過(guò)定義一個(gè)WebappClassLoader類加載器,當(dāng)熱部署時(shí)就將原來(lái)的類加載器廢棄并重新實(shí)例化一個(gè)WebappClassLoader類加載器。但這種方式可能存在內(nèi)存泄漏問(wèn)題,因?yàn)镃lassLoader是一個(gè)結(jié)構(gòu)復(fù)雜的對(duì)象,導(dǎo)致它不能被GC回收的可能性比較多,除了對(duì)ClassLoader對(duì)象有引用可能導(dǎo)致其無(wú)法回收,還可能對(duì)其加載的元數(shù)據(jù)(方法、類、字段等)有引用都會(huì)導(dǎo)致無(wú)法被GC回收。

如上圖,tomcat的資源由不同類加載器加載,這里只看BootstrapClassLoader和WebappClassLoader兩個(gè)類加載器,BootstrapClassLoader負(fù)責(zé)加載rt.jar包的Java.sql.DriverManager,WebappClassLoader負(fù)責(zé)加載web應(yīng)用中的MySQL驅(qū)動(dòng)包,其中有一個(gè)很重要的步驟是mysql的驅(qū)動(dòng)類需要注冊(cè)到DriverManager中,即DriverManager.registerDriver(new Driver()),它由mysql驅(qū)動(dòng)包自動(dòng)完成。這樣一來(lái)當(dāng)web應(yīng)用進(jìn)行熱部署操作時(shí),沒(méi)有將mysql的Driver從DriverManager中反注冊(cè)掉的話,則會(huì)導(dǎo)致整個(gè)WebappClassLoader回收不了,造成內(nèi)存泄漏。
接著看tomcat如何對(duì)此內(nèi)存泄漏進(jìn)行監(jiān)控的,要判斷WebappClassLoader會(huì)不會(huì)導(dǎo)致內(nèi)存泄漏只需判斷WebappClassLoader有沒(méi)有被GC回收即可。在Java中有一種引用叫弱引用,它能很好判斷WebappClassLoader有沒(méi)有被GC回收,被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾回收發(fā)生之前,即如果某WebappClassLoader對(duì)象只被某弱引用關(guān)聯(lián),則它會(huì)在下次垃圾回收時(shí)被回收,但如果WebappClassLoader對(duì)象除了被弱引用關(guān)聯(lián)外還被其他對(duì)象強(qiáng)引用,那么WebappClassLoader對(duì)象是不會(huì)被回收的,根據(jù)這些條件就可以判斷是否有WebappClassLoader內(nèi)存泄漏了。
Tomcat的實(shí)現(xiàn)是通過(guò)WeakHashMap來(lái)實(shí)現(xiàn)弱引用的,只需將WebappClassLoader對(duì)象put到WeakHashMap中,例如weakMap.put(“a”,webappClassLoader),當(dāng)webappClassLoader及其包含的元素沒(méi)有被其它任何類加載器中的元素引用到時(shí),JVM發(fā)生垃圾回收時(shí)則會(huì)把webappClassLoader對(duì)象回收。
簡(jiǎn)單的實(shí)現(xiàn)代碼大致如下:
public class MemoryLeakTest{
private Map<ClassLoader, String> childClassLoaders = new WeakHashMap<ClassLoader, String>();
public String[] findReloadedContextMemoryLeaks() {
System.gc();
List<String> result = new ArrayList<String>();
for (Map.Entry<ClassLoader, String> entry : childClassLoaders.entrySet()) {
ClassLoader cl = entry.getKey();
if (!((WebappClassLoader) cl).isStarted()) {
result.add(entry.getValue());
}
}
return result.toArray(new String[result.size()]);
}
}
使用一個(gè)WeakHashMap用于跟蹤WebappClassLoader,在查找內(nèi)存泄漏之前會(huì)先強(qiáng)制調(diào)用System.gc();進(jìn)行一次垃圾回收,保證沒(méi)問(wèn)題的WebappClassLoader都被回收掉,這時(shí)如果還有WebappClassLoader的狀態(tài)是非started(正常啟動(dòng)的都為started,關(guān)閉了的則為非started)的,則是未被垃圾回收的WebappClassLoader,屬于內(nèi)存泄漏的。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- 詳解如何通過(guò)tomcat的ManagerServlet遠(yuǎn)程部署項(xiàng)目
- servlet和tomcat_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- tomcat中Servlet對(duì)象池介紹及如何使用
- tomcat中Servlet的工作機(jī)制詳細(xì)介紹
- Tomcat報(bào)錯(cuò):HTTP Status 500 (Wrapper cannot find servlet class)解決辦法
- tomcat報(bào)錯(cuò):Wrapper cannot find servlet class ...問(wèn)題解決
- Spring關(guān)閉Tomcat Servlet容器時(shí)內(nèi)存泄漏問(wèn)題解決方案
相關(guān)文章
tomcat?啟動(dòng)時(shí)卡住問(wèn)題排查及解決方法
這篇文章主要介紹了tomcat?啟動(dòng)時(shí)卡住問(wèn)題排查,本文給大家分享完美解決方法,對(duì)tomcat?啟動(dòng)卡住解決方法感興趣的朋友一起看看吧2023-03-03
關(guān)于Tomcat?結(jié)合Atomikos?實(shí)現(xiàn)JTA的方法
Tomcat作為一款經(jīng)典的Web服務(wù)器,在開發(fā)、測(cè)試和生產(chǎn)環(huán)境中得到了廣泛的使用。但Tomcat畢竟不是Java EE服務(wù)器,因此在EJB,JTA方面并沒(méi)有提供支持。本文講述了Tomcat使用Atomikos實(shí)現(xiàn)JTA的一種方法,需要的朋友可以參考下2021-11-11
一文告訴你如何解決Tomcat亂碼問(wèn)題(很詳細(xì)!)
這篇文章主要給大家介紹了關(guān)于如何解決Tomcat亂碼問(wèn)題的相關(guān)資料,還給大家介紹了tomcat窗口中文亂碼的解決方法,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03
web安全—tomcat禁用WebDAV或者禁止不需要的 HTTP 方法
現(xiàn)在主流的WEB服務(wù)器一般都支持WebDAV,使用WebDAV的方便性,呵呵,就不用多說(shuō)了吧,用過(guò)VS.NET開發(fā)ASP.Net應(yīng)用的朋友就應(yīng)該 知道,新建/修改WEB項(xiàng)目,其實(shí)就是通過(guò)WebDAV+FrontPage擴(kuò)展做到的,下面我就較詳細(xì)的介紹一下2017-03-03
詳解tomcat設(shè)置默認(rèn)路徑致使項(xiàng)目url沖突解決方法
這篇文章主要介紹了詳解tomcat設(shè)置默認(rèn)路徑致使項(xiàng)目url沖突解決方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Tomcat安全設(shè)置 win2003 下tomcat權(quán)限限制
Tomcat安全設(shè)置 win2003 下tomcat權(quán)限限制,需要的朋友可以參考下。2011-03-03

