JVM中的五種引用

JVM中的五種引用

在這裏插入圖片描述

  • 強引用:只有所有的GC Roots對象都不通過強引用引用該對象,該對象才能被垃圾回收
  • 軟引用:軟引用需要一個由一個GC Root對象指向一個專門的軟引用對象(SoftReference對象),然後再由軟引用對象指出。僅有軟引用引用該對象時,在垃圾回收後,內存仍不足時會再次觸發垃圾回收,回收如圖上所示的A2對象;而軟引用對象自身則配合引用隊列釋放自己。

軟引用的應用場景:一些不是很重要的資源,當內存不足時可以釋放掉。

// list --> SoftReference —-> byte[]
// list對SoftReference是強引用,但對SoftReference對byte[]是軟引用
List<SoftReference<Byte[]>> list=new ArrayList<>();
ReferenceQueue<byte[]> queue=new ReferenceQueue<>();//引用隊列
for(int i=0;i<5;++i){
	//關聯了引用隊列,當軟引用所關聯的byte[]回收時,軟引用自己也會加入到queue中去
		SoftReference<Byte[]> ref=new SoftReference<>(new Byte[_4MB]);
		list.add(ref);
}
//從list中刪除掉無效的引用
Reference<? Extends byte[]> poll=queue.poll();
while(poll!=null){
		list.remove(poll);
		poll=queue.poll();
}

如上面所示代碼,用SoftReference類的實例對象指向一個Byte[]對象,這就是軟引用,當虛擬機內存不足時,會回收掉這一部分;同時因爲我們創建了一個引用隊列,當軟引用指向的對象被回收時它自己也會被加入到引用隊列中等待回收。


  • 弱引用:僅有弱引用引用該對象時,在垃圾回收時,無論內存是否充足,都會回收A3;可以配合引用隊列來釋放弱引用自身。
  • 虛引用:以NIO爲例,在創建ByteBuffer的時候,會創建一個名爲Cleaner的虛引用對象,ByteBuffer會分配一個塊直接內存,並把內存地址傳遞給Cleaner;這樣做的目的是當ByteBuffer沒有被強引用時,會被垃圾回收掉,但是直接內存並不能java的垃圾回收管理,此時Cleaner會進入引用隊列,由Reference Handler線程調用Unsafe.freeMemory方法把直接內存釋放掉。
  • 終結器引:Java中所有的類都繼承自Object類,在Object類中有一個finalize()方法,如果某類重新了這個方法,那麼當沒有強引用引用時,虛擬機會創建一個終結器引用指向這個對象,把終結器引用加入到引用隊列,再由一個優先級很低的線程Finalizer去調用A4的finalize()方法。(詳解見JVM垃圾收集器筆記——死亡前的自救
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章