大對象緩存的實現與調用原則

ck2265395 13年前發布 | 1K 次閱讀
大對象緩存的實現與調用原則

在UOP之數據緩存一文中我介紹了對象緩存的一般原則,對其中的大對象緩存只是簡單

介紹了基本原理.本文詳細地說明如何進行大對象緩存.

基于本欄目的類型,在本欄目中討論的內容是如何恰當地應用某種技術來進行系統設計.

而不會介紹某種基本技術.如本文涉及的對象的次(軟)/弱/虛引用的概念,這是你要自己

參看相關資料而掌握的.

大對象(FatObject)是指在創建時要耗費一定時間,或創建完成后要占用一定的空間的對

象,簡單說,就是“"來之不易“"啊.比如圖形對象,Socket連結等.所以這類對象不宜頻繁地創

建.應該盡量使用它的緩沖.對象的緩沖不僅僅指緩存對象本身,而且包括多次復用.

但因為這樣的對象占用了較大的空間,如果使用頻度不高又不能長時間放在內存中,所以在

持久與創建之間產生一個矛盾.既不能每次調都重新創建,又不能一次創建后就永久保持.

算了,這么煩的事,費那么多腦子干什么.交給JVM自己決定好了.

把大對象緩存原則交給JVM自己決定,理由是:

如果JVM發生資源回收,說明現在空間吃緊,那么這類大對象就應該騰出空間了.而平時,JVM

沒有發生資源回收,說明還有一定的空間冗余,那就盡量讓這樣的大對象活得久一些.減少

重復創建的機率.

要達到上面的條件,就是不能有強引用,如果有強引用持有這樣的大對象,那么無論如果JVM

大需要回收資源的時候不會回收這個對象.

所以,我們創建一個大對象后,要么就一直不持有這個對象的強引用,要么在強引用后要立即

將對象和引用之間的關聯打斷.

SoftReferencesr=null;//聲明一個用于存返回對象的指示.

if(sr==nullsr.get()==null){

sr=newSoftReference(newFatObject());

}

我們每次都可以從sr.get()獲取這個大對象,只要sr.get()為null,說明原來那個對象已經

被回收了,下次調用時就要重新生成.

這樣生成的對象,如果我們將它賦給了強引用句柄,如:

Imageimg=(Image)sr.get();

那么在調用img引用完成后,一定要img=null;才能打斷引用句柄img與那個大對象的關聯.

否則,在JVM進行GC時,它就不能被回收,一直占著資源不能釋放.而這樣的編程方式又不符合

常歸的編程習慣,比竟,是自動回收內存的,不象C/C++的程序員在使用對象后會記得手工

清除對象,要讓程序員每次使用完對象后都要手動執行handler=null;這樣的語句實在

不是一回事.

其實,C#的屬性是一個非常好的方式,雖然Class.Attribute象是引用一個類的字段,而實際上

是調用了getXXX方法.在java中我們只好這樣來引用緩存的大對象,雖然仍然不是最常規的習

慣,但比每次調用后都要handler=null;這樣要自然得多了:

classCacahedFatImage{

SoftReferencesr=null;

StringfilePath;

publicCacahedFatImage(StringfilePath){

this.filePath=filePath;

sr=newSoftReference(newImage(filepath));

}

publicImagegetObject(){

if(sr==nullsr.get()==null)

sr=newSoftReference(newImage(filepath));

return(Image)sr.get();

}

}

在調用的時候,先生成CacahedFatImage對象:

CacahedFatImagecfi=newCacahedFatImage();

以后在調用這個大對象的時候都以cfi.getObject()來代替img引用.

如:cfi.getObject().getWidth();

cfi.getObject().getHeight();

這樣,只要這個對象沒有被回收我們就可以隨時獲取到它,而如果JVM需要回收時,因為沒強

引用關系,它可以隨時被回收.

 本文由用戶 ck2265395 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!