介紹Java中的內(nèi)存泄漏
Java語言的一個(gè)關(guān)鍵的優(yōu)勢(shì)就是它的內(nèi)存管理機(jī)制。你只管創(chuàng)建對(duì)象,Java的垃圾回收器幫你分配以及回收內(nèi)存。然而,實(shí)際的情況并沒有那么簡(jiǎn)單,因?yàn)閮?nèi)存泄漏在Java應(yīng)用程序中還是時(shí)有發(fā)生的。
下面就解釋下什么是內(nèi)存泄漏,它為什么會(huì)發(fā)生,以及我們?nèi)绾巫柚顾陌l(fā)生。
1. 什么是內(nèi)存泄漏?內(nèi)存泄漏的定義:對(duì)象已經(jīng)沒有被應(yīng)用程序使用,但是垃圾回收器沒辦法移除它們,因?yàn)檫€在被引用著。
要想理解這個(gè)定義,我們需要先了解一下對(duì)象在內(nèi)存中的狀態(tài)。下面的這張圖就解釋了什么是無用對(duì)象以及什么是未被引用對(duì)象。

Unused and Unreferenced
上面圖中可以看出,里面有被引用對(duì)象和未被引用對(duì)象。未被引用對(duì)象會(huì)被垃圾回收器回收,而被引用的對(duì)象卻不會(huì)。未被引用的對(duì)象當(dāng)然是不再被使用的對(duì)象,因?yàn)闆]有對(duì)象再引用它。然而無用對(duì)象卻不全是未被引用對(duì)象。其中還有被引用的。就是這種情況導(dǎo)致了內(nèi)存泄漏。
2. 為什么會(huì)發(fā)生內(nèi)存泄漏?來先看看下面的例子,為什么會(huì)發(fā)生內(nèi)存泄漏。下面這個(gè)例子中,A對(duì)象引用B對(duì)象,A對(duì)象的生命周期(t1-t4)比B對(duì)象的生命周期(t2-t3)長(zhǎng)的多。當(dāng)B對(duì)象沒有被應(yīng)用程序使用之后,A對(duì)象仍然在引用著B對(duì)象。這樣,垃圾回收器就沒辦法將B對(duì)象從內(nèi)存中移除,從而導(dǎo)致內(nèi)存問題,因?yàn)槿绻鸄引用更多這樣的對(duì)象,那將有更多的未被引用對(duì)象存在,并消耗內(nèi)存空間。
B對(duì)象也可能會(huì)持有許多其他的對(duì)象,那這些對(duì)象同樣也不會(huì)被垃圾回收器回收。所有這些沒在使用的對(duì)象將持續(xù)的消耗之前分配的內(nèi)存空間。

Object-Life-Time
3. 如何防止內(nèi)存泄漏的發(fā)生?下面是幾條容易上手的建議,來幫助你防止內(nèi)存泄漏的發(fā)生。
特別注意一些像HashMap、ArrayList的集合對(duì)象,它們經(jīng)常會(huì)引發(fā)內(nèi)存泄漏。當(dāng)它們被聲明為static時(shí),它們的生命周期就會(huì)和應(yīng)用程序一樣長(zhǎng)。特別注意事件監(jiān)聽和回調(diào)函數(shù)。當(dāng)一個(gè)監(jiān)聽器在使用的時(shí)候被注冊(cè),但不再使用之后卻未被反注冊(cè)。“如果一個(gè)類自己管理內(nèi)存,那開發(fā)人員就得小心內(nèi)存泄漏問題了。” 通常一些成員變量引用其他對(duì)象,初始化的時(shí)候需要置空。 4. 一個(gè)小問題:為什么JDK6中的substirng()方法容易導(dǎo)致內(nèi)存泄漏?要想解答上面的問題,你或許可以看看Substring() in JDK 6 and 7。
外文鏈接:The Introduction of Java Memory Leaks
相關(guān)文章:
1. idea重置默認(rèn)配置的方法步驟2. idea給項(xiàng)目打war包的方法步驟3. IntelliJ IDEA設(shè)置自動(dòng)提示功能快捷鍵的方法4. IntelliJ IDEA安裝插件的方法步驟5. IntelliJ IDEA設(shè)置背景圖片的方法步驟6. idea 打包的jar運(yùn)行報(bào) "XXX中沒有主清單屬性"7. Docker 部署 Prometheus的安裝詳細(xì)教程8. idea打開多個(gè)窗口的操作方法9. IntelliJ IDEA調(diào)整字體大小的方法10. IntelliJ IDEA刪除類的方法步驟

網(wǎng)公網(wǎng)安備