WeakReference和內存泄漏有什麼樣的關係?

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中。這樣可以系統設計得更具彈性。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章