国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 服務(wù)器 > Web服務(wù)器 > 正文

Tomcat 檢測內(nèi)存泄漏實例詳解

2024-09-01 13:49:57
字體:
供稿:網(wǎng)友

 Tomcat如何檢測內(nèi)存泄漏

一般情況下,如果我們重啟web應(yīng)用是通過重啟tomcat的話,則不存在內(nèi)存泄漏問題。但如果不重啟tomcat而對web應(yīng)用進行重加載則可能會導(dǎo)致內(nèi)存泄漏,因為重加載后有可能會導(dǎo)致原來的某些內(nèi)存無法讓GC回收,例如web應(yīng)用使用了JDBC,驅(qū)動會進行注冊,當(dāng)web應(yīng)用停止時沒有反注冊就會導(dǎo)致內(nèi)存泄漏。

看看是什么原因?qū)е聇omcat內(nèi)存泄漏的。這個要從熱部署開始說起,因為tomcat提供了不必重啟容器而只需重啟web應(yīng)用以達到熱部署的功能,其實現(xiàn)是通過定義一個WebappClassLoader類加載器,當(dāng)熱部署時就將原來的類加載器廢棄并重新實例化一個WebappClassLoader類加載器。但這種方式可能存在內(nèi)存泄漏問題,因為ClassLoader是一個結(jié)構(gòu)復(fù)雜的對象,導(dǎo)致它不能被GC回收的可能性比較多,除了對ClassLoader對象有引用可能導(dǎo)致其無法回收,還可能對其加載的元數(shù)據(jù)(方法、類、字段等)有引用都會導(dǎo)致無法被GC回收。

Tomcat如何檢測內(nèi)存泄漏,Tomcat檢測內(nèi)存泄漏詳解

如上圖,tomcat的資源由不同類加載器加載,這里只看BootstrapClassLoader和WebappClassLoader兩個類加載器,BootstrapClassLoader負責(zé)加載rt.jar包的Java.sql.DriverManager,WebappClassLoader負責(zé)加載web應(yīng)用中的MySQL驅(qū)動包,其中有一個很重要的步驟是mysql的驅(qū)動類需要注冊到DriverManager中,即DriverManager.registerDriver(new Driver()),它由mysql驅(qū)動包自動完成。這樣一來當(dāng)web應(yīng)用進行熱部署操作時,沒有將mysql的Driver從DriverManager中反注冊掉的話,則會導(dǎo)致整個WebappClassLoader回收不了,造成內(nèi)存泄漏。

接著看tomcat如何對此內(nèi)存泄漏進行監(jiān)控的,要判斷WebappClassLoader會不會導(dǎo)致內(nèi)存泄漏只需判斷WebappClassLoader有沒有被GC回收即可。在Java中有一種引用叫弱引用,它能很好判斷WebappClassLoader有沒有被GC回收,被弱引用關(guān)聯(lián)的對象只能生存到下一次垃圾回收發(fā)生之前,即如果某WebappClassLoader對象只被某弱引用關(guān)聯(lián),則它會在下次垃圾回收時被回收,但如果WebappClassLoader對象除了被弱引用關(guān)聯(lián)外還被其他對象強引用,那么WebappClassLoader對象是不會被回收的,根據(jù)這些條件就可以判斷是否有WebappClassLoader內(nèi)存泄漏了。

Tomcat的實現(xiàn)是通過WeakHashMap來實現(xiàn)弱引用的,只需將WebappClassLoader對象put到WeakHashMap中,例如weakMap.put(“a”,webappClassLoader),當(dāng)webappClassLoader及其包含的元素沒有被其它任何類加載器中的元素引用到時,JVM發(fā)生垃圾回收時則會把webappClassLoader對象回收。

簡單的實現(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()]);  }}

使用一個WeakHashMap用于跟蹤WebappClassLoader,在查找內(nèi)存泄漏之前會先強制調(diào)用System.gc();進行一次垃圾回收,保證沒問題的WebappClassLoader都被回收掉,這時如果還有WebappClassLoader的狀態(tài)是非started(正常啟動的都為started,關(guān)閉了的則為非started)的,則是未被垃圾回收的WebappClassLoader,屬于內(nèi)存泄漏的。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 新建县| 元江| 保德县| 罗田县| 宝丰县| 广宗县| 新疆| 无为县| 苏州市| 大方县| 嘉定区| 贺州市| 岚皋县| 亚东县| 固原市| 富民县| 安阳市| 凤翔县| 黄浦区| 布尔津县| 邵武市| 曲沃县| 宁化县| 屏东县| 中阳县| 翼城县| 柳河县| 周宁县| 鄂伦春自治旗| 东方市| 九龙县| 礼泉县| 宣城市| 伊金霍洛旗| 襄樊市| 通辽市| 开封市| 福安市| 洞头县| 马鞍山市| 吉林市|