本篇文章給大家分享的是有關(guān)Tomcat與內(nèi)存泄露處理的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
在墨脫等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣,外貿(mào)網(wǎng)站制作,墨脫網(wǎng)站建設(shè)費(fèi)用合理。
但是隨著開(kāi)發(fā)經(jīng)歷的增長(zhǎng),已經(jīng)開(kāi)發(fā)過(guò)應(yīng)用的增多,應(yīng)用內(nèi)需要加載的 class 增多,經(jīng)常就會(huì)遇到內(nèi)存溢出(OOM)?;蛘吒_切的說(shuō),因?yàn)榧虞d class 的增多導(dǎo)致的內(nèi)存溢出是java.lang.OutOfMemoryError: PermGen space
此時(shí),解決OOM的方式一般是
分析應(yīng)用的代碼寫(xiě)的是否有問(wèn)題,可以通過(guò)一些工具觀察應(yīng)用內(nèi)占用內(nèi)存較多的 class 類(lèi)型 (比如通過(guò) JVisualVM 來(lái)分析Java七武器系列多情環(huán) --多功能Profiling工具 JVisual VM,或者通過(guò)MAT來(lái)分析)
修改 JVM啟動(dòng)參數(shù),增大關(guān)于 Perm Gen 的配置。
在 Tomcat 這一類(lèi)的 應(yīng)用服務(wù)器中,由于其做為應(yīng)用的容器運(yùn)行,可能自身的Perm Gen 占用并不多,但需要考慮部署到容器中的應(yīng)用占用。有些應(yīng)用依賴(lài)了大量的第三方類(lèi)庫(kù),也有一些應(yīng)用會(huì)在運(yùn)行時(shí)動(dòng)態(tài)生成大量的 class,這些內(nèi)容的加載,都容易導(dǎo)致 Perm Gen 的 OOM。
對(duì)于 OOM 的處理,內(nèi)部會(huì)在啟動(dòng)時(shí)占用一小塊內(nèi)存,在 OOM 產(chǎn)生的時(shí)候釋放掉來(lái)臨時(shí)緩解一下,這種稱(chēng)為oomParachute。前面寫(xiě)過(guò)一篇介紹的文章(預(yù)防OOM,Tomcat是這樣做的)。
除此之外,Tomcat 在 manager 應(yīng)用中還提供了發(fā)現(xiàn)內(nèi)存泄漏的功能。
圖上說(shuō)明寫(xiě)的明白,該功能主要用于分析在應(yīng)用停止、重部署、解除部署時(shí)是否造成了內(nèi)存泄漏。
在請(qǐng)求后,manager的上方信息顯示區(qū)域會(huì)提示當(dāng)前是否有應(yīng)用造成的內(nèi)存泄漏。
但需要注意的是此功能會(huì)觸發(fā)一次 Full GC 的執(zhí)行,代碼中使用的是 System.gc(),在生產(chǎn)環(huán)境中如果使用需要謹(jǐn)慎。
那么,在什么情況下會(huì)導(dǎo)致所謂的應(yīng)用內(nèi)存泄漏呢?
我們都知道, 為了實(shí)現(xiàn)應(yīng)用間的 class 隔離, Tomcat 對(duì)于每個(gè)應(yīng)用,都會(huì)單獨(dú)使用一個(gè) WebappClassLoader,這樣,多個(gè)應(yīng)用間即使都使用到一個(gè) 類(lèi)庫(kù)的不同版本,也不會(huì)相互影響造成沖突。 (參考前面的文章:Tomcat類(lèi)加載器以及應(yīng)用間class隔離與共享, 類(lèi)加載器與類(lèi)沖突)
但是,在這種情況下,當(dāng)一個(gè)應(yīng)用已經(jīng)執(zhí)行了停止操作,或者執(zhí)行了重部署操作,此時(shí)是會(huì)生成一個(gè)新的 classLoader 來(lái)加載新部署的應(yīng)用類(lèi)信息。
我們知道,在 Java 中,類(lèi)與類(lèi)之間是存在引用關(guān)系的,類(lèi)似于強(qiáng)引用,弱引用,幻影引用,用來(lái)在GC時(shí)將一些不需要的 class 回收掉,騰出空間。按理說(shuō)之前的 classLoader 本應(yīng)該被垃圾回收,但在某些時(shí)候,由于一些類(lèi)之前的引用關(guān)系導(dǎo)致該 classLoader,以及其加載的一系列 class 文件, 都不能被標(biāo)識(shí)為垃圾,此時(shí)這些 class 依然駐留在 Perm Gen,隨著應(yīng)用多次啟停,多次重部署之后,出現(xiàn)了 Perm Gen 的 OOM。
一般以下類(lèi)庫(kù)的使用容易導(dǎo)致 class loader 逃過(guò)垃圾回收,產(chǎn)生內(nèi)存泄漏:
JDBC driver 注冊(cè)
一些 logging 框架
沒(méi)有移除的 ThreadLocal的使用
未停止的 Thread
此外,一些 Java API 的使用也容易導(dǎo)致此問(wèn)題,例如
javax.imageio API
XML 解析
RMI 使用
由于這些容易占用 classLoader,導(dǎo)致其不能被回收,如果這些 class 交給各個(gè)應(yīng)用的類(lèi)加載器進(jìn)行加載,就會(huì)使得 Perm Gen 中這些類(lèi)越來(lái)越多,從而產(chǎn)生泄漏。
為此,在 Tomcat 中引入了 JreMemoryLeakPreventionListener這個(gè)組件。實(shí)現(xiàn)思路是在 Tomcat 啟動(dòng)時(shí),通過(guò) System class Loader 來(lái)加載這些類(lèi)。 由于類(lèi)加載器的加載原理(默認(rèn)父優(yōu)先,而且這些系統(tǒng)的類(lèi),都會(huì)委托給系統(tǒng)類(lèi)加載器進(jìn)行加載),這些類(lèi)不會(huì)再被 WebclassLoader 重新加載,從而減小內(nèi)存泄漏的產(chǎn)生。
默認(rèn)在 Tomcat 的配置 server.xml 中已經(jīng)開(kāi)啟了該組件,所以這些功能你已經(jīng)不知不覺(jué)中在使用。
以上就是Tomcat與內(nèi)存泄露處理的示例分析,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。