四種引用 強引用 弱引用 軟引用和虛引用

2022-09-24 06:45:14 字數 3775 閱讀 8616

j**a執行gc判斷物件是否存活有兩種方式其中一種是引用計數

引用計數:j**a堆中每乙個物件都有乙個引用計數屬性,引用每新增1次計數加1,引用每釋放1次計數減1。

jdk 1.2以前的版本中,若乙個物件不被任何變數引用,那麼程式就無法再使用這個物件。也就是說,只有物件處於(reachable)可達狀態,程式才能使用它。

jdk 1.2版本開始,物件的引用被劃分為4種級別,從而使程式能更加靈活地控制物件的生命週期。這4種級別由高到低依次為:強引用、軟引用、弱引用和虛引用

在 j**a 中最常見的就是強引用,把乙個物件賦給乙個引用變數,這個引用變數就是乙個強引

。當乙個物件被強引用變數引用時,它處於可達狀態,它是不可能被垃圾**機制**的,即

使該物件以後永遠都不會被用到 jvm 也不會**。因此強引用是造成 j**a 記憶體洩漏的主要原因之

一。

object strongreference = new object();
當記憶體空間不足時,j**a虛擬機器寧願丟擲outofmemoryerror錯誤,使程式異常終止,也不會靠隨意**具有強引用的物件來解決記憶體不足的問題。

在乙個方法的內部有乙個強引用,這個引用儲存在j**a中,而真正的引用內容(object)儲存在j**a中。當這個方法執行完成後,就會退出方法棧,則引用物件的引用數為0,這個物件會被**。

public void test()
顯式地設定strongreference物件為null,或讓其超出物件的生命週期範圍,則gc認為該物件不存在引用,這時就可以**這個物件。具體什麼時候收集這要取決於gc演算法。

strongreference = null;
軟引用需要用 softreference 類來實現,對於只有軟引用的物件來說,當系統記憶體足夠時它不會被**,當系統記憶體空間不足時它會被**

軟引用通常用在對記憶體敏感的程式中。

// 強引用

string strongreference = new string("abc");

// 軟引用

string str = new string("abc");

softreferencesoftreference = new softreference(str);

gc執行緒會在虛擬機器丟擲outofmemoryerror之前**軟引用物件,而且虛擬機會盡可能優先**長時間閒置不用的軟引用物件。對那些剛構建的或剛使用過的「較新的」軟物件會被虛擬機器盡可能保留,這就是引入引用佇列referencequeue的原因。

弱引用需要用 weakreference 類來實現,它比軟引用的生存期更短,對於只有弱引用的物件

來說,只要垃圾**機制一執行,不管 jvm 的記憶體空間是否足夠,總會**該物件占用的記憶體。

string str = new string("abc");

weakreferenceweakreference = new weakreference<>(str);

如果乙個物件是偶爾(很少)的使用,並且希望在使用時隨時就能獲取到,但又不想影響此物件的垃圾收集,那麼你應該用weak reference來記住此物件。

虛引用需要 phantomreference 類來實現,它不能單獨使用,必須和引用佇列聯合使用。引用的主要作用是跟蹤物件被垃圾**的狀態。虛引用並不會決定物件的生命週期。如果乙個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾**器**。

string str = new string("abc");

referencequeue queue = new referencequeue();

// 建立虛引用,要求必須與乙個引用佇列關聯

phantomreference pr = new phantomreference(str, queue);

引用佇列,在檢測到適當的可到達性更改後,垃圾**器將已註冊的引用物件新增到該佇列中。

softreference、weakreference的構造方法都有referencequeue的過載

referencequeue主要是用於監聽reference所指向的物件是否已經被垃圾**

當大量使用reference時,雖然reference指向的物件可能被**了,但reference本身也是個物件,所以也需要**。這時就需要使用referencequeue了。

當softreference或weakreference的get()加入referencequeue或get()返回null時,僅是表明其指向的物件已經進入垃圾**流程,此時物件不一定已經被垃圾**。當phantomreference加入referencequeue時,則表明物件已經被**。

referencequeuereferencequeue = new referencequeue<>();

string str = new string("abc");

softreferencesoftreference = new softreference<>(str, referencequeue);

str = null;

// notify gc

system.gc();

system.out.println(softreference.get()); // abc

reference extends string> reference = referencequeue.poll();

system.out.println(reference); //null

j**a中4種引用的級別和強度由高到低依次為:強引用 -> 軟引用 -> 弱引用 -> 虛引用

當垃圾**器**時,某些物件會被**,某些不會被**。垃圾**器會從根物件object來標記存活的物件,然後將某些不可達的物件和一些引用的物件進行**。

引用型別

被垃圾**時間

用途生存時間

強引用從來不會

物件的一般狀態

jvm停止執行時終止

軟引用當記憶體不足時

物件快取

記憶體不足時終止

弱引用正常垃圾**時

物件快取

垃圾**後終止

虛引用正常垃圾**時

跟蹤物件的垃圾**

垃圾**後終止

強引用,軟引用,弱引用,虛引用

強引用就是我們通常意義上的引用,類似 object object new object 只要強引用在,就不會被gc。軟引用,這種物件就是拿來jvm拿來防止記憶體溢位的乙個措施,當jvm要進行記憶體洩露的時候就會把這種物件進行 如果記憶體還不夠,才會丟擲outofmemoryerror。softref...

強引用,軟引用,弱引用

強引用 強引用設定為空,物件立馬會被 public class normalreference classm 軟引用 軟引用當引用存在的時候,只有當記憶體不足的時候才去 public class t0 softreference catch exception e system.out.printl...

java 軟引用 弱引用 虛引用

軟引用 用softreference類來標記,被軟引用標記的物件,只有在記憶體不足的時候,gc才會 該物件。弱引用 用weakreference類來標記,被弱引用標記的物件,在gc時,無論記憶體是否充足,都會被 掉。虛引用 用phantomreference來標記,虛引用需要有乙個與之關聯的引用佇列...