內存泄露分析

1.1 Java對象致使的泄漏

當一個對象的被引用數爲0時,就會被JVM的GC回收。對象有不一樣的引用級別,從最強到最弱,不一樣的引用(可到達性)級別反映了對象的生命週期。java

  1. Strong Ref(強引用):一般咱們編寫的代碼都是Strong Ref,於此對應的是強可達性,只有去掉強可達,對象才被回收。
  2. Soft Ref(軟引用):對應軟可達性,只要有足夠的內存,就一直保持對象,直到發現內存吃緊且沒有Strong Ref時纔回收對象。通常可用來實現緩存,經過java.lang.ref.SoftReference類實現。
  3. Weak Ref(弱引用):比Soft Ref更弱,當發現不存在Strong Ref時,馬上回收對象而沒必要等到內存吃緊的時候。經過java.lang.ref.WeakReference和java.util.WeakHashMap類實現。
  4. Phantom Ref(虛引用):根本不會在內存中保持任何對象,你只能使用Phantom Ref自己。通常用於在進入finalize()方法後進行特殊的清理過程,經過 java.lang.ref.PhantomReference實現。

 

Java對象的泄漏,可分爲暫時不釋放,長期不釋放,沒法釋放幾種。緩存

1.1 底層致使的泄露

上層Java不少功能須要依賴於系統底層的c庫來提供,設計不夠好的jni接口在正常使用時可能沒有什麼問題,可是不少時候,在稍微不注意的狀況下,就算上層的java對象釋放了,若是沒有顯式的調用jni的釋放接口,也會致使底層c庫中的泄漏問題。app

 

1.1 註冊沒取消形成的內存泄漏

一些Android程序可能引用咱們的Android程序的對象(好比註冊機制)。即便咱們的Android程序已經結束了,可是別的引用程序仍然還有對咱們的Android程序的某個對象的引用,泄漏的內存依然不能被垃圾回收。常見的有:設計

BraodcastReceiver,ContentObserver,FileObserver。  server

 

對於上述兩種常見的內存泄漏,咱們在開發中須要記住如下2點: 對象

1. 對activity的持久引用,對activity的引用應該和activity自己有相同的生命週期,儘可能使用application代替activity做爲Context來獲取資源,或者構造Dialog或Toast。 接口

2. 若是不能控制非靜態的內部類的生命週期,儘可能在activity中避免有非靜態的內部類。同時在activity中使用靜態的類時若是須要引用activity,應該採用WeakReference弱引用來引用Activity。生命週期

 

1.1 底層系統資源的泄漏

好比PowerManager.WakeLock,MemoryFile等不少os對象。內存

相關文章
相關標籤/搜索