強引用
強引用是使用最普遍的引用:Object o=new Object();
特點:不會被GC
將對象的引用顯示地置為null:o=null; 幫助垃圾收集器回收此對象
例如ArrayList的clear()
方法的源代碼:
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
軟引用
用來描述一些還有用但是并非必須的對象胀葱,在Java中用java.lang.ref.SoftReference類來表示勺美;對于軟引用關聯(lián)著的對象惶凝,只有在內(nèi)存不足的時候JVM才會回收該對象饲握。因此党远,這一點可以很好地用來解決OOM的問題,并且這個特性很適合用來實現(xiàn)緩存:比如網(wǎng)頁緩存欠气、圖片緩存等铁孵。
User user=new User();
SoftReference softReference=new SoftReference(user);
User user1= (User) softReference.get();
剛才說道當內(nèi)存不足的時候user
會被回收,softReference.get()
會返回null
旧巾,但是softReference
本身也是一個強引用耸序,避免太多softReference
導致內(nèi)存泄漏,軟引用可以和一個引用隊列(ReferenceQueue)聯(lián)合使用鲁猩,如果軟引用所引用的對象被垃圾回收器回收坎怪,Java虛擬機就會把這個軟引用加入到與之關聯(lián)的引用隊列中;從名字可以看出它是一個隊列廓握,我們可以通過這個隊列來把這些失去所軟引用的對象的SoftReference對象清除掉
//聯(lián)合使用
ReferenceQueue queue = new ReferenceQueue();
User user=new User();
SoftReference softReference=new SoftReference(user,queue);
User user1= (User) softReference.get();
//清除的方式
SoftReference ref = null;
while ((ref = (EmployeeRef) q.poll()) != null) {
// 清除ref
}
弱引用
弱引用和軟引用的區(qū)別在于搅窿,弱引用的生命周期很短,在垃圾回收器掃描它管轄的內(nèi)存區(qū)域的過程中疾棵,一旦發(fā)現(xiàn)弱引用對象馬上會被回收戈钢;不過因為垃圾回收器的線程很低痹仙,所以不一定馬上就發(fā)現(xiàn)那些只具有弱引用的對象
虛引用
一個對象是都有虛引用的存在都不會對生存時間都構成影響是尔,也無法通過虛引用來獲取對一個對象的真實引用。唯一的用處:能在對象被GC時收到系統(tǒng)通知开仰,JAVA中用PhantomReference來實現(xiàn)虛引用拟枚。
LruCache
可以利用軟引用、弱引用來實現(xiàn)緩存众弓;但是在Android已經(jīng)提供了一種緩存策略恩溅,LruCache;
LRU(Least Recently Used)緩存算法谓娃,是近期最少使用算法脚乡,它的核心思想是當緩存滿的時候,會優(yōu)先淘汰那些近期最少使用的緩存對象滨达。采用LRU算法的緩存有兩種:LrhCache和DisLruCache奶稠,分別用于實現(xiàn)內(nèi)存緩存和硬盤緩存,其核心思想都是LRU緩存算法捡遍。
使用
//圖片緩存
private LruCache<String, Bitmap> mImageCache;
private void initImageCache() {
//計算可使用的最大內(nèi)存锌订,進程能夠拿到的最大內(nèi)存
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
//取四分之一作為緩存
int cacheSize = maxMemory / 4;
mImageCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
//重寫sizeOf方法,計算出要緩存的每張圖片的大小
protected int sizeOf(String key, Bitmap bitmap) {
//Bitmap所占用的內(nèi)存空間數(shù)等于Bitmap的每一行所占用的空間數(shù)乘以Bitmap的行數(shù)
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
};
}
mImageCache.put(url, bitmap);
Bitmap bitmap = mImageCache.get(url);
實現(xiàn)原理
LruCache是個泛型類画株,把對象儲存在LinkedHashMap中辆飘;LruCache維護一個緩存對象列表啦辐,對象列表的排列方式是按照訪問順序實現(xiàn)的,最近訪問的對象放在隊尾蜈项,沒被訪問的對象自然被擠到隊頭芹关,隊頭的對象最容易被擠掉,被淘汰
參考文章: