天天看點

四種引用及WeakHashMap四種引用WeakHashMap總結

四種引用

強引用

Object object =new Object();

String str =“hello”;

強引用有引用變量指向時永遠不會被垃圾回收,JVM甯願抛出OutOfMemory錯誤也不會回收這種對象。

軟引用

如果一個對象具有軟引用,隻有當記憶體空間不足了,才會回收這些對象的記憶體。隻要垃圾回收器沒有回收它,該對象就可以被程式使用。

四種引用及WeakHashMap四種引用WeakHashMap總結

主函數

class MyArray{
    byte[] array = new byte[1024 * 1024 * 3];
}
public class SoftReferenceTest {
    public static void main(String[] args) {
        //引用隊列:存儲被GC回收的對象
        ReferenceQueue<MyArray> queue = new ReferenceQueue<>();
        //軟引用的方式建立,w就是MyArray的軟引用
        SoftReference<MyArray> w = new SoftReference<>(new MyArray(),queue);
        System.out.println("記憶體足夠時:"+queue.poll());
        //此處需要3M的記憶體,記憶體不夠了,是以觸發GC,回收軟引用對象
        byte[] array = new byte[1024 * 1024 * 3];
        //軟引用對象被回收後存到引用隊列中
        System.out.println("記憶體不夠後:"+queue.poll());
    }
}
           

結果

四種引用及WeakHashMap四種引用WeakHashMap總結

弱引用

隻被弱引用關聯的對象,當GC觸發時,不管記憶體是否夠用,都會回收。

主函數

public class WeakReferenceTest {
    public static void main(String[] args) {
        ReferenceQueue<MyArray> queue = new ReferenceQueue<>();
        WeakReference<MyArray> w = new WeakReference<>(new MyArray(),queue);
        System.out.println("記憶體足夠時:"+queue.poll());
        System.gc();//手動調用gc
        System.out.println("調用gc後:"+queue.poll());
    }
}
           

結果

四種引用及WeakHashMap四種引用WeakHashMap總結

虛引用

虛引用和前面的軟引用、弱引用不同,它并不影響對象的生命周期。

如果一個對象與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。設定虛引用的目的是在這個對象被GC回收時收到一個系統通知。

主函數

public class PhantomReferenceTest {
    public static void main(String[] args) {
        ReferenceQueue<MyArray> queue = new ReferenceQueue<>();
        //建立虛引用
        PhantomReference<MyArray> w = new PhantomReference<>(new MyArray(),queue);
        System.out.println(queue.poll());
        System.gc();
        try {
            Thread.sleep(1000);//讓gc充分發生
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(queue.poll());
    }
}
           

結果

四種引用及WeakHashMap四種引用WeakHashMap總結

WeakHashMap

特點

存儲的key都是弱引用。

繼承的接口

public class WeakHashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V> 
           

其内部的Entry繼承了WeakReference,也就是弱引用,是以就具有了弱引用的特點。ReferenceQueue的作用是GC會清理掉對象之後,引用對象會被放到ReferenceQueue中。

使用

public class WeakHashMapTest {
    public static void main(String[] args) {
        WeakHashMap<String,Integer> map = new WeakHashMap<>();
        String str1 = new String("123");
        String str2 = new String("456");
        map.put(str1,100);map.put(str2,200);
        Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String, Integer> next = iterator.next();
            System.out.println("key:"+next.getKey()+"  value:"+next.getValue());
        }
        str1 = null;//釋放強引用
        System.gc();
        System.out.println("---------------------------");
        Iterator<Map.Entry<String, Integer>> iterator1 = map.entrySet().iterator();
        while(iterator1.hasNext()){
            Map.Entry<String, Integer> next = iterator1.next();
            System.out.println("key:"+next.getKey()+"  value:"+next.getValue());
        }
    }
}
           

結果

四種引用及WeakHashMap四種引用WeakHashMap總結

總結

HashMap和WeakHashMap的不同之處?

  1. WeakHashMap不能使用clone方法,不能進行序列化。
  2. WeakHashMap存儲資料時,如果key為空,會用Object對象替換null,實際上存儲的是new Object();,但列印的還是null。
  3. WeakHashMap的key不能使用基礎資料類型。