自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Tomcat與內(nèi)存泄露處理

開發(fā) 開發(fā)工具
隨著開發(fā)經(jīng)歷的增長,已經(jīng)開發(fā)過應(yīng)用的增多,應(yīng)用內(nèi)需要加載的 class 增多,經(jīng)常就會遇到內(nèi)存溢出(OOM)。那么,我們該如何處理呢?

似乎從 Java 入門的時候,就有這樣的說法來考查 Java開發(fā)者:

Java 不像 C++ 那樣自己管理內(nèi)存,有Java 虛擬機負(fù)責(zé)進行垃圾回收,再也沒有內(nèi)存泄露的問題了。

但是隨著開發(fā)經(jīng)歷的增長,已經(jīng)開發(fā)過應(yīng)用的增多,應(yīng)用內(nèi)需要加載的 class 增多,經(jīng)常就會遇到內(nèi)存溢出(OOM)?;蛘吒_切的說,因為加載 class 的增多導(dǎo)致的內(nèi)存溢出是

  1. java.lang.OutOfMemoryError: PermGen space 

此時,解決OOM的方式一般是:

1. 分析應(yīng)用的代碼寫的是否有問題,可以通過一些工具觀察應(yīng)用內(nèi)占用內(nèi)存較多的 class 類型 (比如通過 JVisualVM 來分析Java七武器系列多情環(huán) --多功能Profiling工具 JVisual VM,或者通過MAT來分析)

2. 修改 JVM啟動參數(shù),增大關(guān)于 Perm Gen 的配置。

在 Tomcat 這一類的 應(yīng)用服務(wù)器中,由于其做為應(yīng)用的容器運行,可能自身的Perm Gen 占用并不多,但需要考慮部署到容器中的應(yīng)用占用。有些應(yīng)用依賴了大量的第三方類庫,也有一些應(yīng)用會在運行時動態(tài)生成大量的 class,這些內(nèi)容的加載,都容易導(dǎo)致 Perm Gen 的 OOM。

對于 OOM 的處理,內(nèi)部會在啟動時占用一小塊內(nèi)存,在 OOM 產(chǎn)生的時候釋放掉來臨時緩解一下,這種稱為oomParachute。

除此之外,Tomcat 在 manager 應(yīng)用中還提供了發(fā)現(xiàn)內(nèi)存泄漏的功能。

Tomcat 在 manager 應(yīng)用中還提供了發(fā)現(xiàn)內(nèi)存泄漏的功能

圖上說明寫的明白,該功能主要用于分析在應(yīng)用停止、重部署、解除部署時是否造成了內(nèi)存泄漏。

在請求后,manager的上方信息顯示區(qū)域會提示當(dāng)前是否有應(yīng)用造成的內(nèi)存泄漏。

manager的上方信息顯示區(qū)域會提示當(dāng)前是否有應(yīng)用造成的內(nèi)存泄漏

但需要注意的是此功能會觸發(fā)一次 Full GC 的執(zhí)行,代碼中使用的是 System.gc(),在生產(chǎn)環(huán)境中如果使用需要謹(jǐn)慎。

那么,在什么情況下會導(dǎo)致所謂的應(yīng)用內(nèi)存泄漏呢?

我們都知道, 為了實現(xiàn)應(yīng)用間的 class 隔離, Tomcat 對于每個應(yīng)用,都會單獨使用一個 WebappClassLoader,這樣,多個應(yīng)用間即使都使用到一個 類庫的不同版本,也不會相互影響造成沖突。

但是,在這種情況下,當(dāng)一個應(yīng)用已經(jīng)執(zhí)行了停止操作,或者執(zhí)行了重部署操作,此時是會生成一個新的 classLoader 來加載新部署的應(yīng)用類信息。

我們知道,在 Java 中,類與類之間是存在引用關(guān)系的,類似于強引用,弱引用,幻影引用,用來在GC時將一些不需要的 class 回收掉,騰出空間。按理說之前的 classLoader 本應(yīng)該被垃圾回收,但在某些時候,由于一些類之前的引用關(guān)系導(dǎo)致該 classLoader,以及其加載的一系列 class 文件, 都不能被標(biāo)識為垃圾,此時這些 class 依然駐留在 Perm Gen,隨著應(yīng)用多次啟停,多次重部署之后,出現(xiàn)了 Perm Gen 的 OOM。

一般以下類庫的使用容易導(dǎo)致 class loader 逃過垃圾回收,產(chǎn)生內(nèi)存泄漏:

  • JDBC driver 注冊
  • 一些 logging 框架
  • 沒有移除的 ThreadLocal的使用
  • 未停止的 Thread

此外,一些 Java API 的使用也容易導(dǎo)致此問題,例如

  • javax.imageio API
  • XML 解析
  • RMI 使用

由于這些容易占用 classLoader,導(dǎo)致其不能被回收,如果這些 class 交給各個應(yīng)用的類加載器進行加載,就會使得 Perm Gen 中這些類越來越多,從而產(chǎn)生泄漏。

為此,在 Tomcat 中引入了JreMemoryLeakPreventionListener 這個組件。實現(xiàn)思路是在 Tomcat 啟動時,通過 System class Loader 來加載這些類。 由于類加載器的加載原理(默認(rèn)父優(yōu)先,而且這些系統(tǒng)的類,都會委托給系統(tǒng)類加載器進行加載),這些類不會再被 WebclassLoader 重新加載,從而減小內(nèi)存泄漏的產(chǎn)生。

默認(rèn)在 Tomcat 的配置 server.xml 中已經(jīng)開啟了該組件,所以這些功能你已經(jīng)不知不覺中在使用。

【本文為51CTO專欄作者“侯樹成”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號『Tomcat那些事兒』獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2017-10-26 08:43:18

JavaScript內(nèi)存處理

2009-06-16 11:11:07

Java內(nèi)存管理Java內(nèi)存泄漏

2015-05-14 15:38:40

javajava內(nèi)存泄露

2011-11-17 13:59:41

Java內(nèi)存管理內(nèi)存泄露

2019-02-28 14:28:35

內(nèi)存泄露tomcat調(diào)優(yōu)

2017-04-13 13:00:27

LinuxWindowstomcat

2010-10-25 10:10:27

ibmdwJava

2010-09-25 11:23:15

Java內(nèi)存泄露

2017-02-21 16:40:16

Android垃圾回收內(nèi)存泄露

2017-12-11 11:00:27

內(nèi)存泄露判斷

2017-11-15 19:30:08

Python內(nèi)存泄露循環(huán)引用

2013-08-07 10:07:07

Handler內(nèi)存泄露

2022-10-10 11:37:14

Gomap內(nèi)存

2011-07-20 17:04:43

Objective-C 內(nèi)存 內(nèi)存泄露

2010-06-02 13:00:43

Linux 內(nèi)存監(jiān)控

2010-08-10 10:00:57

Flex內(nèi)存

2016-09-12 16:01:28

Android內(nèi)存泄露內(nèi)存管理

2013-12-23 09:25:21

2010-09-25 11:32:24

Java內(nèi)存泄漏

2022-08-26 07:33:49

內(nèi)存JVMEntry
點贊
收藏

51CTO技術(shù)棧公眾號