1.什么是內(nèi)存泄漏
當(dāng)一個對象已經(jīng)不需要再使用本該被回收時屈雄,另外一個正在使用的對象持有它的引用從而導(dǎo)致它不能被回收,這導(dǎo)致本該被回收的對象不能被回收而停留在堆內(nèi)存中膘掰,這就產(chǎn)生了內(nèi)存泄漏猾担。
本質(zhì):
長期存活對象引用短期存活對象陕壹,導(dǎo)致短期存活對象占用的對象無法回收。
2.產(chǎn)生內(nèi)存泄漏情況
1.靜態(tài)集合類
如HashMap共郭、LinkedList等等祠丝。如果這些容器為靜態(tài)的,那么它們的生命周期與程序一致除嘹,則容器中的對象在程序結(jié)束之前將不能被釋放写半,從而造成內(nèi)存泄漏。簡單而言尉咕,長生命周期的對象持有短生命周期對象的引用叠蝇,盡管短生命周期的對象不再使用,但是因為長生命周期對象持有它的引用而導(dǎo)致不能被回收年缎。
2.各種連接悔捶,數(shù)據(jù)庫連接铃慷、網(wǎng)絡(luò)連接和IO連接等
在對數(shù)據(jù)庫進(jìn)行操作的過程中,首先需要建立與數(shù)據(jù)庫的連接蜕该,當(dāng)不再使用時犁柜,需要調(diào)用close方法來釋放與數(shù)據(jù)庫的連接。只有連接被關(guān)閉后堂淡,垃圾回收器才會回收對應(yīng)的對象馋缅。否則,如果在訪問數(shù)據(jù)庫的過程中绢淀,對Connection萤悴、Statement或ResultSet不顯性地關(guān)閉,將會造成大量的對象無法被回收皆的,從而引起內(nèi)存泄漏稚疹。
3.變量不合理的作用域
一般而言,一個變量的定義的作用范圍大于其使用范圍祭务,很有可能會造成內(nèi)存泄漏内狗。另一方面,如果沒有及時地把對象設(shè)置為null义锥,很有可能導(dǎo)致內(nèi)存泄漏的發(fā)生柳沙。
4.緩存泄漏
內(nèi)存泄漏的另一個常見來源是緩存,一旦你把對象引用放入到緩存中拌倍,他就很容易遺忘赂鲤,對于這個問題,可以使用WeakHashMap代表緩存柱恤,此種Map的特點是数初,當(dāng)除了自身有對key的引用外,此key沒有其他引用那么此map會自動丟棄此值
5.監(jiān)聽器和回調(diào)
如果客戶端在你實現(xiàn)的API中注冊回調(diào)梗顺,卻沒有顯示的取消泡孩,那么就會積聚。
3.解決方法
對jvm的堆內(nèi)存進(jìn)行dump寺谤,只有拿到這個文件我們才能分析出jvm堆內(nèi)存中到底存了些什么內(nèi)容仑鸥,到底在做什么?然后定位具體代碼变屁,修改代碼解決問題
具體:
使用內(nèi)存映像分析工具對dump出來的堆轉(zhuǎn)儲快照進(jìn)行分析眼俊,可以通過工具查看泄露對象到GC Roots的引用鏈,掌握泄露對象的信息粟关,從而確定泄露的代碼位置進(jìn)行修改