欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解析Android開發(fā)優(yōu)化之:軟引用與弱引用的應(yīng)用

 更新時(shí)間:2013年05月09日 10:02:03   作者:  
Java從JDK1.2版本開始,就把對(duì)象的引用分為四種級(jí)別,從而使程序能更加靈活的控制對(duì)象的生命周期。這四種級(jí)別由高到低依次為:強(qiáng)引用、軟引用、弱引用和虛引用,本篇文章重點(diǎn)介紹一下軟引用和弱引用

如果一個(gè)對(duì)象只具有軟引用,那么如果內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存。只要垃圾回收器沒有回收它,該對(duì)象就可以被程序使用。軟引用可用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存。軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

如果一個(gè)對(duì)象只具有弱引用,那么在垃圾回收器線程掃描的過程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存。不過,由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。弱引用也可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

弱引用與軟引用的根本區(qū)別在于:只具有弱引用的對(duì)象擁有更短暫的生命周期,可能隨時(shí)被回收。而只具有軟引用的對(duì)象只有當(dāng)內(nèi)存不夠的時(shí)候才被回收,在內(nèi)存足夠的時(shí)候,通常不被回收。

在java.lang.ref包中提供了幾個(gè)類:SoftReference類、WeakReference類和PhantomReference類,它們分別代表軟引用、弱引用和虛引用。ReferenceQueue類表示引用隊(duì)列,它可以和這三種引用類聯(lián)合使用,以便跟蹤Java虛擬機(jī)回收所引用的對(duì)象的活動(dòng)。

在Android應(yīng)用的開發(fā)中,為了防止內(nèi)存溢出,在處理一些占用內(nèi)存大而且聲明周期較長的對(duì)象時(shí)候,可以盡量應(yīng)用軟引用和弱引用技術(shù)。

下面以使用軟引用為例來詳細(xì)說明。弱引用的使用方式與軟引用是類似的。

假設(shè)我們的應(yīng)用會(huì)用到大量的默認(rèn)圖片,比如應(yīng)用中有默認(rèn)的頭像,默認(rèn)游戲圖標(biāo)等等,這些圖片很多地方會(huì)用到。如果每次都去讀取圖片,由于讀取文件需要硬件操作,速度較慢,會(huì)導(dǎo)致性能較低。所以我們考慮將圖片緩存起來,需要的時(shí)候直接從內(nèi)存中讀取。但是,由于圖片占用內(nèi)存空間比較大,緩存很多圖片需要很多的內(nèi)存,就可能比較容易發(fā)生OutOfMemory異常。這時(shí),我們可以考慮使用軟引用技術(shù)來避免這個(gè)問題發(fā)生。

首先定義一個(gè)HashMap,保存軟引用對(duì)象。

復(fù)制代碼 代碼如下:

private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();

再來定義一個(gè)方法,保存Bitmap的軟引用到HashMap。
復(fù)制代碼 代碼如下:

 public void addBitmapToCache(String path) {

        // 強(qiáng)引用的Bitmap對(duì)象

        Bitmap bitmap = BitmapFactory.decodeFile(path);

        // 軟引用的Bitmap對(duì)象

        SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);

        // 添加該對(duì)象到Map中使其緩存

        imageCache.put(path, softBitmap);

    }


獲取的時(shí)候,可以通過SoftReference的get()方法得到Bitmap對(duì)象。
復(fù)制代碼 代碼如下:

public Bitmap getBitmapByPath(String path) {

        // 從緩存中取軟引用的Bitmap對(duì)象

        SoftReference<Bitmap> softBitmap = imageCache.get(path);

        // 判斷是否存在軟引用

        if (softBitmap == null) {

            return null;

        }

        // 取出Bitmap對(duì)象,如果由于內(nèi)存不足Bitmap被回收,將取得空

        Bitmap bitmap = softBitmap.get();

        return bitmap;

    }


使用軟引用以后,在OutOfMemory異常發(fā)生之前,這些緩存的圖片資源的內(nèi)存空間可以被釋放掉的,從而避免內(nèi)存達(dá)到上限,避免Crash發(fā)生。

需要注意的是,在垃圾回收器對(duì)這個(gè)Java對(duì)象回收前,SoftReference類所提供的get方法會(huì)返回Java對(duì)象的強(qiáng)引用,一旦垃圾線程回收該Java對(duì)象之后,get方法將返回null。所以在獲取軟引用對(duì)象的代碼中,一定要判斷是否為null,以免出現(xiàn)NullPointerException異常導(dǎo)致應(yīng)用崩潰。


經(jīng)驗(yàn)分享:

到底什么時(shí)候使用軟引用,什么時(shí)候使用弱引用呢?

個(gè)人認(rèn)為,如果只是想避免OutOfMemory異常的發(fā)生,則可以使用軟引用。如果對(duì)于應(yīng)用的性能更在意,想盡快回收一些占用內(nèi)存比較大的對(duì)象,則可以使用弱引用。

還有就是可以根據(jù)對(duì)象是否經(jīng)常使用來判斷。如果該對(duì)象可能會(huì)經(jīng)常使用的,就盡量用軟引用。如果該對(duì)象不被使用的可能性更大些,就可以用弱引用。

另外,和弱引用功能類似的是WeakHashMap。WeakHashMap對(duì)于一個(gè)給定的鍵,其映射的存在并不阻止垃圾回收器對(duì)該鍵的回收,回收以后,其條目從映射中有效地移除。WeakHashMap使用ReferenceQueue實(shí)現(xiàn)的這種機(jī)制。

相關(guān)文章

最新評(píng)論