1. 程式人生 > >Android記憶體洩漏與記憶體溢位

Android記憶體洩漏與記憶體溢位

Android記憶體洩漏與記憶體溢位

記憶體洩漏

什麼是記憶體洩漏

某個物件在該釋放的時候由於被其他物件持有而沒有被釋放,即new出來的物件在記憶體中無法被GC回收,造成記憶體洩露。
記憶體洩漏發生時的主要表現為記憶體抖動,可用記憶體慢慢變少。在AndroidStudio中的AndroidMonitor(memory)中可以觀察App的記憶體使用情況。

記憶體洩漏的原因

  1. 靜態變數引用了Activity物件。
  2. 屬性動畫導致的記憶體洩漏。
    如果在Activity中播放無限迴圈的屬性動畫,且在onDestory中未停止動畫,則在Activity銷燬後,雖然在介面上無法看到動畫效果,但此時Activity中的某個View會被該動畫持有,而View又持有了Activity,最終Activity無法釋放。
    需要通過在onDestory中呼叫animator.cancel()來停止動畫防止記憶體洩漏。

記憶體洩漏檢測工具LeakCanary

通過LeakCanary可以為我們找到記憶體洩漏的位置,但並不能夠提供我們記憶體洩漏的原因,有時記憶體洩漏的位置是由於其他原因導致的。

Java中的記憶體分配

  1. 靜態儲存區:編譯時就分配好,在程式整個執行期間都存在。它主要存放靜態資料和常量;
  2. 棧區:當方法執行時,會在棧區記憶體中建立方法體內部的區域性變數,方法結束後自動釋放記憶體;
  3. 堆區:通常存放new出來的物件。由Java垃圾回收器回收。

Java中的四種引用型別

  1. 強引用(StrongReference):JVM寧可丟擲OOM,也不會讓GC回收具有強引用的物件;
  2. 軟引用(SoftReference):只有在記憶體空間不足時,才會被回收的物件;
  3. 弱引用(WeakReference):在GC時,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體;
  4. 虛引用(PhantomReference):任何時候都可以被GC回收,當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之關聯的引用佇列中。程式可以通過判斷引用佇列中是否存在該物件的虛引用,來了解這個物件是否將要被回收。可以用來作為GC回收Object的標誌。

騰訊記憶體洩漏分析

https://zhuanlan.zhihu.com/p/25213586