Java四種引用類型
1.引用的基本概念
強引用:當我們使用new創建對象時,被創建的對象就是強引用,如Object object = new Object(),其中的object就是一個強引用了。如果一個對象具有強引用,JVM就不會去GC它,JVM寧可會報OOM來終止程序,也不回收該對象。
軟引用: 如果一個對象只具備軟引用,如果內存空間足夠,那么JVM就不會GC它,如果內存空間不足了,就會GC該對象。
弱引用: 如果一個對象只具有弱引用,只要JVM的GC線程檢測到了,就會立即回收。弱引用的生命周期要比軟引用短很多。不過,如果垃圾回收器是一個優先級很低的線程,也不一定會很快就會釋放掉軟引用的內存。
虛引用:如果一個對象只具有虛引用,那么它就和沒有任何引用一樣,隨時會被JVM當作垃圾進行GC。
上面的四種引用對應的是new關鍵字以及java.lang.ref包中的SoftReference,WeakReference, PhantomReference。我們注意到在java.lang.ref包中,還存在一個類叫做ReferenceQueue。
2.理解ReferenceQueue
當軟引用對象被GC之后,雖然這個SoftReference對象指向的對象已不存在,但這個SoftReference對象本身還占用內存,因此需要一個適當的清除機制,避免大量SoftReference對象帶來的OOM。這就需要用到ReferenceQueue。如果在創建SoftReference對象的時候,使用了一個ReferenceQueue對象作為參數提供給SoftReference的構造方法,如下例子:
- ReferenceQueue queue = new ReferenceQueue();
- SoftReference ref=new SoftReference(new MyObject(), queue);
那么當這個SoftReference指向的MyOhject對象被垃圾收集器回收的同時,ref對象本身會被放入ReferenceQueue。也就是說,ReferenceQueue中保存的對象是Reference對象,但這些Reference對象引用的對象已經不存在了。
我們可以調用ReferenceQueue的poll()方法來檢查是否有它所關心的非強引用對象被回收。利用這個方法,我們可以檢查哪個SoftReference所軟引用的對象已經被回收。於是我們可以把這些失去軟引用的對象的清除掉。
3.理解WeakHashMap
WeakHashMap是以弱引用為鍵實現的HsahMap。更精確地說,對於一個給定的key對象,其對應的value對象的存在並不能阻止該key對象被GC。GC某個key對象時,它所在的條目會一並被從Map中刪除。這是WeakHashMap與其他HashMap最大的不同。看下面的例子:
- import java.util.Iterator;
- import java.util.WeakHashMap;
- public class Demo{
- public static void main(String [] args) throws Exception{
- WeakHashMap<String,String> weakHashMap=new WeakHashMap<String, String>();
- String [] sts=new String[10];
- for(int i=0;i<100;i++){
- if(i%10==0) {
- sts[i/10]=new String(""+i);
- weakHashMap.put(sts[i/10], new String(""+i));
- }
- else
- weakHashMap.put(new String(""+i), new String(""+i));
- }
- // 催促垃圾回收器工作
- System.gc();
- // 把CPU讓給垃圾回收器線程
- Thread.sleep(8000);
- Iterator<String> iterator=weakHashMap.keySet().iterator();
- while(iterator.hasNext()){
- System.out.println(iterator.next());
- }
- }
- }