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來標記,虛引用需要有乙個與之關聯的引用佇列...