ThreadLocal前奏:我理解的java四種引用型別
前言
為了理解ThreadLocal,掌握引用的概念是非常有必要的。
引用與物件
java中我們通過一個引用指向記憶體中物件。
//建立一個引用,引用可以獨立存在,並不一定需要與一個物件關聯
User user;
user = new User();
複製程式碼
user是引用, 通過‘=’指向了記憶體中的物件。
四種引用
JDK1.2後,根據對物件的引用強度不同,將引用分為4種型別。
強引用:
平時使用最多,最普遍的引用。
User user;
user = new User();//強引用
複製程式碼
- user就是強引用
- 堆中的User物件例項,就是“被應用”;
只要user 指向 User物件。User物件就不會被回收。
user = null;斷開了引用,User物件不可達,會被回收。
複製程式碼
軟引用:
我們可以通過SoftReference
來定義一個軟引用
SoftReference<User> softRef=new SoftReference<User>(new User());//軟引用
複製程式碼
- 如果一個物件只有軟引用,記憶體足夠時,GC時不回收他。如果內容空間不足時,就會回收被軟引用指向的物件記憶體。
- 只要沒有別回收,還可以使用
解釋下:物件只有軟引用 物件有兩種引用的情況
User user = new User();//強引用
SoftReference<User> softRef=new SoftReference<User>(user);//軟引用
複製程式碼
物件只有軟引用情況
SoftReference<User> softRef=new SoftReference<User>(new User());//軟引用
複製程式碼
或
User user = new User();//強引用
SoftReference<User> softRef=new SoftReference<User>(user);//軟引用
user = null;//斷開了強引用。 此時只有軟引用。
複製程式碼
軟引用可與引用佇列(ReferenceQueue)聯合使用,在建立軟引用時,關聯ReferenceQueue。如果軟引用引用的物件被回收時,Java虛擬機器器會把這個軟引用加入到與之關聯的引用佇列中。
軟引用可用作記憶體敏感的快取記憶體。
弱引用:
可以通過WeakReference
來定義一個弱引用
WeakReference<> weak = new WeakReference<>(new User());//定義一個軟引用指向堆內User物件
複製程式碼
- 如果物件只有弱引用,GC時,不管記憶體是否足夠。都會回收,弱引用指向的物件。
弱引用也可與引用佇列(ReferenceQueue)聯合使用,在建立弱引用時,關聯ReferenceQueue。如果弱引用引用的物件被回收時,Java虛擬機器器會把這個弱引用加入到與之關聯的引用佇列中。
ThreadLocal 中使用到了弱引用。
虛引用:
虛引用是最弱的引用,弱到,不能用弱引用訪問到物件。
可以通過PhantomReference
來定義一個虛引用。
虛引用,主要用來跟蹤物件被垃圾回收器回收的活動。
虛引用必須與引用佇列(ReferenceQueue)一起使用,當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之 關聯的引用佇列中。我們可以根據引用是否在佇列中,來判斷物件的回收活動。
為什麼需要不同的引用型別
我們看出引用強度的不同,物件的生命週期不同,垃圾回收策略豐富,有利於更好的管理物件記憶體。
總結:
- 引用與物件的生命週期相關。
- 物件可以被多種型別的,多個引用指向,但只要有一個強引用。垃圾回收器不回收。
關鍵時理解: 一個物件,可以被多種型別引用同時指向,強度最高的決定他的生命週期。
注意:這裡的記憶體應該是指“堆記憶體”,並且區分引用型別與基本型別
//String user ="user";//
String user = new String("user");
SoftReference<String> softRef=new SoftReference<String>(user);
WeakReference<String> weak = new WeakReference<String>(user);
user=null;
System.out.println(softRef.get());
System.gc();
System.out.println(weak.get());
複製程式碼