天天看點

怎麼用弱引用實作記憶體洩漏檢測

在Java中,引用分為強引用、軟引用、弱引用和虛引用四種。

強引用,代碼中普遍存在的形式,例如常見的普通類new出對象後的引用。GC不會回收強引用的對象。

軟引用,軟引用對象會在記憶體溢出異常之前進行回收,也就是說在記憶體富裕的情況下GC不回收軟引用。它可通過SoftReference類實作。

弱引用,弱引用對象會在下一次GC時被回收,也就是說不管記憶體富不富裕,當GC時都會回收弱引用。它可通過WeakReference類實作。

虛引用,虛引用不會改變對象的生存時間,它隻是讓對象在被GC時能收到一個系統通知。

了解了所有引用類型後看下如何基于弱引用對程式進行記憶體洩漏檢測。

假如在你的程式中有某類的對象很可能會造成記憶體洩漏,姑且稱為MaybeMemoryLeak類。記憶體洩漏就是虛拟機在做垃圾回收時某些“垃圾”由于某些原因而導緻無法回收,每次執行個體化出來的對象都無法回收,最終導緻記憶體爆了。也就是如果某些MaybeMemoryLeak應該被回收的對象無法回收,就會導緻記憶體洩漏。

如果無法避免記憶體洩漏的可能性,那麼如何檢測記憶體洩漏現象呢?

這裡就要用到上面所說的弱引用,它能很好判斷MaybeMemoryLeak有沒有被GC回收,被弱引用關聯的對象隻能生存到下一次垃圾回收發生之前,即如果某MaybeMemoryLeak對象隻被某弱引用關聯,則它會在下次垃圾回收時被回收,但如果MaybeMemoryLeak對象除了被弱引用關聯外還被其他對象強引用,那麼MaybeMemoryLeak對象是不會被回收的,根據這些條件就可以判斷是否有MaybeMemoryLeak記憶體洩漏了。

在實際的實作中可以通過WeakHashMap來實作弱引用,隻需将MaybeMemoryLeak對象put到WeakHashMap中,例如weakMap.put(“a”,maybeMemoryLeak),當maybeMemoryLeak及其包含的元素沒有被其它任何類加載器中的元素引用到時,JVM發生垃圾回收時則會把maybeMemoryLeak對象回收,否則就将一直回收不了。

這裡使用一個WeakHashMap用于追蹤MaybeMemoryLeak對象,在查找記憶體洩漏之前要先強制調用System.gc();進行一次垃圾回收,保證沒問題的MaybeMemoryLeak對象都被回收掉,這時可以檢視WeakHashMap對象還存在哪些MaybeMemoryLeak對象,如果存在某些“垃圾”MaybeMemoryLeak對象,則屬于記憶體洩漏。

====廣告時間,可直接跳過====

=========================

歡迎關注:

怎麼用弱引用實作記憶體洩漏檢測