銜接上篇:
新年事後獻上關於Android內存泄漏的種種總結
(順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)git
在Android應用的開發中,爲了防止內存溢出,在處理一些佔用內存大並且聲明周 期較長的對象時候,能夠儘可能應用軟引用和弱引用技術。github
軟/弱引用能夠和一個引用隊列(ReferenceQueue)聯合使用,若是軟引用所引用 的對象被垃圾回收器回收,Java虛擬機就會把這個軟引用加入到與之關聯的引用隊 列中。利用這個隊列能夠得知被回收的軟/弱引用的對象列表,從而爲緩衝器清除已 失效的軟/弱引用。 面試
假設咱們的應用會用到大量的默認圖片,好比應用中有默認的頭像,默認遊戲圖標 等等,這些圖片不少地方會用到。若是每次都去讀取圖片,因爲讀取文件須要硬件 操做,速度較慢,會致使性能較低。因此咱們考慮將圖片緩存起來,須要的時候直 接從內存中讀取。可是,因爲圖片佔用內存空間比較大,緩存不少圖片須要不少的 內存,就可能比較容易發生OutOfMemory異常。這時,咱們能夠考慮使用軟/弱引 用技術來避免這個問題發生。數組
如下就是高速緩衝器的雛形: 首先定義一個HashMap,保存軟引用對象。緩存
private Map <String, SoftReference<Bitmap>> imageCache = new Has hMap <String, SoftReference<Bitmap>> ();
再來定義一個方法,保存Bitmap的軟引用到HashMap
。
使用軟引用之後,在OutOfMemory異常發生以前,這些緩存的圖片資源的內存空間 能夠被釋放掉的,從而避免內存達到上限,避免Crash發生。 若是隻是想避免OutOfMemory異常的發生,則可使用軟引用。架構
若是對於應用的性 能更在乎,想盡快回收一些佔用內存比較大的對象,則可使用弱引用。 app
另外能夠根據對象是否常用來判斷選擇軟引用仍是弱引用。若是該對象可能會 常用的,就儘可能用軟引用。若是該對象不被使用的可能性更大些,就能夠用弱 引用ide
ok,繼續回到主題。前面所說的,建立一個靜態Handler內部類,而後對 Handler 持有的對象使用弱引用,這樣在回收時也能夠回收 Handler 持有的對象,可是這樣 作雖然避免了 Activity 泄漏,不過 Looper
線程的消息隊列中仍是可能會有待處理的 消息,因此咱們在 Activity 的 Destroy 時或者 Stop 時應該移除消息隊列 MessageQueue
中的消息。 oop
下面幾個方法均可以移除 Message:性能
public final void removeCallbacks(Runnable r); public final void removeCallbacks(Runnable r, Object token); public final void removeCallbacksAndMessages(Object token); public final void removeMessages(int what); public final void removeMessages(int what, Object object);
儘可能避免使用 static 成員變量
若是成員變量被聲明爲 static,那咱們都知道其生命週期將與整個app進程生命 週期同樣。
這會致使一系列問題,若是你的app進程設計上是長駐內存的,那即便app切到 後臺,這部份內存也不會被釋放。按照如今手機app內存管理機制,佔內存較 大的後臺進程將優先回收,由於若是此app作過進程互保保活,那會形成app在 後臺頻繁重啓。當手機安裝了你參與開發的app之後一晚上時間手機被消耗空了 電量、流量,你的app不得不被用戶卸載或者靜默。 這裏修復的方法是:
不要在類初始時初始化靜態成員。能夠考慮lazy初始化。 架構設計上要思考是否真 的有必要這樣作,儘可能避免。若是架構須要這麼設計,那麼此對象的生命週期你有 責任管理起來。
override finalize()
二、finalize 方法只會被執行一次,即便對象被複活,若是已經執行過了 finalize 方法,再次被 GC 時也不會再執行了,緣由是:
含有 finalize
方法的 object 是在 new 的時候由虛擬機生成了一個 finalize reference
在來引用到該Object的,而在 finalize 方法執行的時候,該 object 所 對應的 finalize Reference
會被釋放掉,即便在這個時候把該 object 復活(即用 強引用引用住該 object ),再第二次被 GC 的時候因爲沒有了 finalize reference
與之對應,因此 finalize 方法不會再執行。
三、含有Finalize方法的object須要至少通過兩輪GC纔有可能被釋放。
BraodcastReceiver
,ContentObserver
,File,遊標 Cursor, Stream,Bitmap等資源的使用,應該在Activity銷燬時及時關閉或者註銷,否 則這些資源將不會被回收,形成內存泄漏。好比:
構造 Adapter 時,沒有使用緩存的 convertView
,每次都在建立新的 converView
。這裏推薦使用 ViewHolder
。
getApplicationContext
或者 getApplication
,以免 Activity 被外部長 生命週期的對象引用而泄露。Activity onStop
或者 onDestroy
的時候,取消掉該 Handler
對象的 Message
和 Runnable
.BraodcastReceiver
,ContentObserver
,File,遊 標 Cursor,Stream,Bitmap等資源的使用,應該在Activity銷燬時及時關閉或 者註銷。 刪減了一部分,見諒^_^
(順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)