https://juejin.im/post/5d06de9d51882559ee6f4212?utm_source=gold_browser_extension
1.首先,四種引用如下:
- FinalReference 強引用
- SoftReference 軟引用
- WeakReference 弱引用
- PhantomReference 虛引用
2.四種引用的特點:
強引用:被new出來的對象都是的引用都是強引用
eg:Student s = new Student();
回收時機:不會被回收,會發生內存溢出。
軟引用:軟引用關聯的對象,在內存不夠的情況下,會把這些軟引用關聯的對象列入垃圾回收范圍中,然后進行回收,也就是說軟引用並非是完全安全的,在內存不夠的情況下是會被垃圾回收器回收掉的。
public static void main(String[] args) { SoftReference[] references = new SoftReference[5]; ReferenceQueue<ReferenceTestObject> referenceTestObjectReferenceQueue = new ReferenceQueue<>(); for(int i =0 ;i<5;i++){ references[i] = new SoftReference(new ReferenceTestObject("ahahh-"+i),referenceTestObjectReferenceQueue); } for(int i =0 ;i<5;i++){ Object o = references[i].get(); if(o == null){ System.out.println("null"); }else{ System.out.println(((ReferenceTestObject)o).name); } } }
使用場景:使用軟引用來保存從數據庫中取出的數據,具體是做了一個中間層的封裝,該中間層的作用就是在get出數據的時候會去判斷數據是否為null,如果是為null再次從數據庫讀取,讀取后再放入軟引用的集合中,這樣的做法是可以避免內存溢出。
弱引用:只要發生GC都會被回收掉
eg:ThreadLocalMap的key
static class ThreadLocalMap { /** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object). Note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table. Such entries are referred to * as "stale entries" in the code that follows. */ static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } ......}
虛引用
有和沒有一個樣:無法通過虛引用來獲取對象的實例,但是還是有作用的。、
作用就是能在這個對象被收集器回收時收到一個系統通知,實現追蹤垃圾收集器的回收動作,比如在對象被回收的時候,會調用該對象的finalize方法。
ReferenceQueue 引用隊列:
在創建Reference時,手動將Queue注冊到Reference中,而當該Reference所引用的對象被垃圾收集器回收時,JVM會將該Reference放到該隊列中,而我們便可以對該隊列做些其他業務,相當於一種通知機制。
可達性分析:

對象4、5、6都是可被回收的。 那么問題來了,哪些對象可以作為GC Roots呢? 這里給出幾個,如下
-
虛擬機棧中引用的對象
-
方法區中類靜態屬性引用的對象
-
方法區中常量引用的對象
-
本地方法棧JNI引用的對象