java中有哪幾種引用?它們的含義和區別是什麼
在jdk1.2之前,java中引用的定義:如果引用型別的資料型別中儲存的數值代表的是一塊記憶體的起始地址,就稱這塊記憶體代表一個引用。在jdk1.2之後,java引入了4種物件引用型別,級別由高到低分別是:強引用、軟引用、弱引用和虛引用。
為什麼需要不同的引用
對於需要長期執行的應用程式來說,如果無用的物件所佔的記憶體空間無法及時釋放的話,那麼在一個區域性的時間段裡就會形成事實上的記憶體洩露,如果要及時地釋放記憶體,在java中最穩妥的方式就是在使用完物件過後 立即執行“object = null”,當然這這是理想狀態。
通過這4種引用型別 強行呼叫垃圾回收方法 System.gc() 來解決記憶體洩露的問題,不同的引用方式會有不同的作用,下面我們來一一講解。
- 強引用(StrongReference):直接引用物件,記憶體不足時也不會回收
- 軟引用(SoftReference):記憶體不足時,回收引用相關聯的物件
- 弱引用 (WeakReference):無論記憶體是否充足,都回收引用相關聯的物件
- 虛引用(PhantomReference):任何時候都可以被垃圾回收器回收
強引用
強引用是日常程式設計中最常用的一種引用型別,它的特點是隻要引用存在,就永遠不會呼叫垃圾回收方法對其進行釋放記憶體,java虛擬機器寧可出現OutOfMemoryError錯誤停止執行,也會儲存記憶體空間。只用當這個物件的引用被釋放掉,物件才會被釋放。
正是因為強引用具備這樣的特點,所以我們的開發原則是儘量少例項化物件。
強引用是造成java記憶體洩露的主要原因之一。
軟引用
軟引用是指非必須引用,在記憶體足夠時是不會對其進行回收,而在記憶體不足的時候垃圾回收器會將其回收並釋放記憶體。java中軟引用對應著SoftReference類,如果想要一個物件被軟引用,只需要將其作為引數傳入SoftReference類的構造方法中就行了。
軟引用主要用於使用者實現類似快取的功能,在記憶體足夠的情況下直接通過軟引用取值,無需從繁忙的真實來源查詢資料,提升速度;當記憶體不足時,自動刪除這部分快取資料,從真實來源查詢這些資料。軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收器回收,java虛擬機器就會把這個軟引用加入到與之關聯的佇列引用中。
弱引用
弱引用相對於軟引用,被弱引用的物件擁有更短的記憶體時間(生命週期)。垃圾回收器一旦發現了被弱引用的物件,就會回收它的記憶體,不管當前記憶體空間是不是足夠。不過,由於垃圾回收器是一個優先順序很低的執行緒,因此不一定很快發現那些弱引用的物件。對應java中的WeakReference類,使用方法與軟引用基本相同,弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收器回收,java虛擬機器就會把這個軟引用加入到與之關聯的佇列引用中。
弱引用主要應用於監控物件是否被垃圾回收器標記為即將回收的垃圾,可以通過弱引用的isEnQueued方法返回物件是否被垃圾回收器標記
虛引用
顧名思義:形同虛設,虛引用並不會決定物件的生命週期,如果一個物件僅有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。程式也不能通過虛引用訪問被引用的物件。
虛引用主要用來跟蹤垃圾回收器回收的活動,虛引用與弱應用,軟引用的區別在於:虛引用必須和引用佇列(ReferenceQueue)聯合使用,當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件記憶體之前,把這個虛引用加入到與之關聯的佇列中。
程式碼
/**
* 強引用
*/
public static void main(String[] args) {
Object object = new Object();//強引用
Object ref = object;//引用傳遞
System.out.println(object);
boolean equals = object.equals(new Object()); //可直接通過obj取得對應的物件
System.out.println(equals);
object = null;//斷開引用與物件的連結
System.gc();
System.out.println(object);
System.out.println(ref);
}
/**
* 弱引用
*/
public static void main(String[] args) {
Object object = new Object();
SoftReference<Object> reference = new SoftReference<Object>(object);
object = null;
System.out.println(reference.get());
// System.gc();//對比弱引用
// System.out.println(reference.get());
final String str = "1111111111111111111111111111111111111111";//用於佔用記憶體,建立一個final且字元較多的字串
String string = "";
try {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
string = string + str;
string.intern();//該方法返回一個規範化表示的string物件。一個字串常量池,初始化為空,且被String類私有地維護。
// 當intern()被呼叫時,如果常量池中存在和該String物件equal的物件(由equals方法決定),則返回常量池中已有的String物件,若不存在,則將該物件加入常量池,並返回該物件的引用。
}
} catch (Throwable throwable) {
System.out.println("----------errot--");
}
System.out.println(reference.get());//結果:null 切勿多次執行結果,否則電腦記憶體會約佔越多,變卡
}
/**
* 弱引用
*/
public static void main(String[] args) {
Object object = new Object();
WeakReference<Object> reference = new WeakReference<Object>(object);
object = null;
System.out.println(reference.get());//結果:java.lang.Object@610455d6
System.gc();
System.out.println(reference.get());//結果:null
}
/**
* 虛引用
*/
public static void main(String[] args) {
ReferenceQueue<String> queue = new ReferenceQueue<>();
String string = new String("hello");
PhantomReference<String> reference = new PhantomReference<String>(string,queue);
System.out.println(reference.get());
}
相關文章
- python和C語言哪個難?它們的區別是什麼?PythonC語言
- Linux中斷訊號有幾種?它們之間的區別是什麼?Linux
- CISC和RISC是什麼?它們的特點和區別?
- Python和Go是什麼?它們之間有什麼區別?PythonGo
- Linux中連結分為哪兩種?它們有什麼區別?Linux
- 請教大家元件和模組有什麼區別,它們的概念分別是什麼?元件
- 什麼是中斷?什麼是異常?它們有何區別?
- CSRF與SSRF是什麼?它們之間有什麼區別?
- Java自動化測試框架有哪幾類、區別是什麼?Java框架
- 加密演算法是什麼?有哪幾種型別?有什麼用?加密演算法型別
- Session是什麼?它與Cookie有什麼區別?SessionCookie
- Java(3)-POJO和Java bean的區別是什麼JavaPOJOBean
- 什麼是Yottachain和YTA幣,它們是什麼關係?AI
- Java和Python是什麼?有什麼區別?JavaPython
- dns汙染是誰幹的,什麼是dns汙染,它和DNS劫持有什麼區別DNS
- Linux由哪幾部分組成?與Ubuntu的區別是什麼?LinuxUbuntu
- Web含義是什麼Web
- 【Java面試】Mybatis中#{}和${}的區別是什麼?Java面試MyBatis
- EJB和Java Beans的區別是什麼啊JavaBean
- 什麼是元宇宙系統開發?它的價值有什麼含義?元宇宙
- Java和HTML有什麼區別?哪個更重要?JavaHTML
- 什麼是負載均衡?有哪幾種策略?負載
- Java 介面和抽象類是什麼,有什麼區別Java抽象
- top得到的cpu幾個值到底是什麼含義?
- 深入探究Java中equals()和==的區別是什麼Java
- 什麼是萬用字元SSL證書?它和多域名SSL證書的區別是什麼?字元
- js中=、==、===三個的區別是什麼?並說明它們各自的工作過程JS
- 什麼是XSS攻擊?XSS攻擊有哪幾種型別?型別
- Linux和windows系統哪個好?區別是什麼?LinuxWindows
- 什麼是企業中臺?它和低程式碼平臺有什麼區別?
- Tomcat的配置檔案中有哪些關鍵的配置項,它們分別有什麼作用?Tomcat
- 什麼是PCB?什麼是PCBA?PCB和PCBA的區別?
- 強引用、軟引用、弱引用、幻象引用有什麼區別?
- cat和vim的區別是什麼?
- python is和==的區別是什麼?Python
- HIVE和HBASE的區別是什麼Hive
- JDO和JPA的區別是什麼?
- 為什麼 Go 有兩種宣告變數的方式,有什麼區別,哪種好?Go變數