四種引用
強引用
Object object =new Object();
String str =“hello”;
強引用有引用變量指向時永遠不會被垃圾回收,JVM甯願抛出OutOfMemory錯誤也不會回收這種對象。
軟引用
如果一個對象具有軟引用,隻有當記憶體空間不足了,才會回收這些對象的記憶體。隻要垃圾回收器沒有回收它,該對象就可以被程式使用。

主函數
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());
}
}
結果
弱引用
隻被弱引用關聯的對象,當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());
}
}
結果
虛引用
虛引用和前面的軟引用、弱引用不同,它并不影響對象的生命周期。
如果一個對象與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。設定虛引用的目的是在這個對象被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
特點
存儲的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());
}
}
}
結果
總結
HashMap和WeakHashMap的不同之處?
- WeakHashMap不能使用clone方法,不能進行序列化。
- WeakHashMap存儲資料時,如果key為空,會用Object對象替換null,實際上存儲的是new Object();,但列印的還是null。
- WeakHashMap的key不能使用基礎資料類型。