WeakReference和內存泄漏有什麼樣的關係?
好像,沒關係
那麼WeakReference又是什麼?
讓我們先描述一個問題:
我有一個對象a(它非常的消耗內存,比如一個bitmap),當你同時申請了20個對象在android中,你將會看到out of memory異常
但是,如果你不緩存圖片,那麼用戶將會認爲你的app的性能非常差:
當你的應用涉及到gridview,而每一個item都是一個圖片時
一個矛盾:不加載圖片(性能低下) vs 加載圖片(加載多了,程序會掛)
一個解決:
只加載有限的圖片,如5個圖片
是的,這能解決問題
但是,你要爲此付出的是什麼:手動編寫加載策略,以及,釋放策略
WeakReference是什麼:
先不看官方doc,讓我們舉個例子:
對象a非常的消耗內存,我有一個WeakReference對象(wra),並且和對象a關聯:(wra & a are good friends)
那麼,在虛擬機看來是什麼樣子呢:wra對象不是個垃圾,但是和wra對象相關聯的對象(對象a)被認爲是垃圾
是的,垃圾就是垃圾,但是:垃圾並不會立刻被清理
也就意味着:你仍然可以使用對象a,如果它還沒被清理的情況下
如果對象a已經被清理呢:你必須重新構建對象a,再一次,和wra關聯
那樣做有什麼樣的好處:
你將可以肆無忌憚的申請任意多個“非常消耗內存”的對象(前提是,讓他們和WeakReference關聯)
使用這些對象前,先判定他們有沒有被清理
如果是,重新構建該對象(可能重新構建並不繁瑣)
如果不是,直接使用
總結:WeakReference負責了:釋放策略
與WeakReference類似的還有:SoftReference,大同小異
WeakReference類似於可有可無的東西。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存,說白了就是一個沒那麼strong要求垃圾回收器將一個對象保留在內存中。不過,由於垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象*********************************************************
事實,並不是,看上去很美
我曾經做過實驗,按照WeakReference的做法,編寫程序,在android2.2上,程序運行正常
但是,同一套代碼運行在android4.0上,程序崩潰:out of memory
正是爲了避免OOM異常,我採用了WeakReference
但是,,,,,
WeakReference,不靠譜
在2.2 vs 4.0上
***************************weakReference vs SoftReference************************
WeakReference是弱引用,其中保存的對象實例可以被GC回收掉。這個類通常用於在某處保存對象引用,而又不干擾該對象被GC回收,通常用於Debug、內存監視工具等程序中。因爲這類程序一般要求即要觀察到對象,又不能影響該對象正常的GC過程。
最近在JDK的Proxy類的實現代碼中也發現了Weakrefrence的應用,Proxy會把動態生成的Class實例暫存於一個由Weakrefrence構成的Map中作爲Cache。
SoftReference是強引用,它保存的對象實例,除非JVM即將OutOfMemory,否則不會被GC回收。這個特性使得它特別適合設計對象Cache。對於Cache,我們希望被緩存的對象最好始終常駐內存,但是如果JVM內存吃緊,爲了不發生OutOfMemoryError導致系統崩潰,必要的時候也允許JVM回收Cache的內存,待後續合適的時機再把數據重新Load到Cache中。這樣可以系統設計得更具彈性。