導航:首頁 > 編程語言 > java引用被回收

java引用被回收

發布時間:2023-09-25 09:23:34

java虛擬機怎麼判斷對象沒被引用從而回收,什麼時候會回收,什麼時候會銷毀

1. 引用計數器演算法
解釋
系統給每個對象添加一個引用計數器,每當有一個地方引用這個對象的時候,計數器就加1,當引用失效的時候,計數器就減1,在任何一個時刻計數器為0的對象就是不可能被使用的對象,因為沒有任何地方持有這個引用,這時這個對象就被視為內存垃圾,等待被虛擬機回收
優點
客觀的說,引用計數器演算法,他的實現很簡單,判定的效率很高,在大部分情況下這都是相當不錯的演算法
其實,很多案例中都使用了這種演算法,比如 IOS 的Object-C , 微軟的COM技術(用於給window開發驅動,.net裡面的技術幾乎都是建立在COM上的),Python語言等.
缺陷
無法解決循環引用的問題.
這就好像是懸崖邊的人採集草葯的人, 想要活下去就必須要有一根繩子綁在懸崖上. 如果有兩個人, 甲的手拉著懸崖, 乙的手拉著甲, 那麼這兩個人都能活, 但是, 如果甲的手拉著乙, 乙的手也拉著甲, 雖然這兩個人都認為自己被別人拉著, 但是一樣會掉下懸崖.
比如說 A對象的一個屬性引用B,B對象的一個屬性同時引用A A.b = B() B.a = A(); 這個A,B對象的計數器都是1,可是,如果沒有其他任何地方引用A,B對象的時候,A,B對象其實在系統中是無法發揮任何作用的,既然無法發揮作用,那就應該被視作內存垃圾予以清理掉,可是因為此時A,B的計數器的值都是1,虛擬機就無法回收A,B對象,這樣就會造成內存浪費,這在計算機系統中是不可容忍的.
解決辦法
在語言層面處理, 例如Object-C 就使用強弱引用類型來解決問題.強引用計數器加1 ,弱引用不增加
Java中也有強弱引用
2. 可達性分析演算法
解釋
這種演算法通過一系列成為 "GC Roots " 的對象作為起始點,從這些節點開始向下搜索所有走過的路徑成為引用鏈(Reference Chain) , 當一個對象GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達),則證明此對象是不可用的
優點
這個演算法可以輕松的解決循環引用的問題
大部分的主流java虛擬機使用的都是這種演算法
3. Java語言中的GC Roots
在虛擬機棧(其實是棧幀中的本地變數表)中引用的對象
在方法區中的類靜態屬性引用對象
在方法區中的常量引用的對象
在本地方法棧中JNI(即一般說的Native方法)的引用對象

㈡ java中垃圾回收有哪幾種機制

強引用
在一般的Java程序中,見到最多的就是強引用(strong reference)。如Date date = new Date(),date就是一個對象的強引用。對象的強引用可以在程序中到處傳遞。很多情況下,會同時有多個引用指向同一個對象。強引用的存在限制了對象在內存中的存活時間。假如對象A中包含了一個對象B的強引用,那麼一般情況下,對象B的存活時間就不會短於對象A。如果對象A沒有顯式的把對象B的引用設為null的話,就只有當對象A被垃圾回收之後,對象B才不再有引用指向它,才可能獲得被垃圾回收的機會。
除了強引用之外,java.lang.ref包中提供了對一個對象的不同的引用方式。JVM的垃圾回收器對於不同類型的引用有不同的處理方式。
軟引用

軟引用(soft reference)在強度上弱於強引用,通過類SoftReference來表示。它的作用是告訴垃圾回收器,程序中的哪些對象是不那麼重要,當內存不足的時候是可以被暫時回收的。當JVM中的內存不足的時候,垃圾回收器會釋放那些只被軟引用所指向的對象。如果全部釋放完這些對象之後,內存還不足,才會拋出OutOfMemory錯誤。軟引用非常適合於創建緩存。當系統內存不足的時候,緩存中的內容是可以被釋放的。比如考慮一個圖像編輯器的程序。該程序會把圖像文件的全部內容都讀取到內存中,以方便進行處理。而用戶也可以同時打開多個文件。當同時打開的文件過多的時候,就可能造成內存不足。如果使用軟引用來指向圖像文件內容的話,垃圾回收器就可以在必要的時候回收掉這些內存。
publicclass ImageData {
private String path;
private SoftReference<byte[]> dataRef;
public ImageData(String path) {
this.path = path;
dataRef = new SoftReference<byte[]>(newbyte[0]);
}
privatebyte[] readImage() {
returnnewbyte[1024 * 1024]; //省略了讀取文件的操作 }
publicbyte[] getData() {
byte[] dataArray = dataRef.get();
if (dataArray == null || dataArray.length == 0) {
dataArray = readImage();
dataRef = new SoftReference<byte[]>(dataArray);
}
return dataArray;
}
}

在運行上面程序的時候,可以使用 -Xmx 參數來限制JVM可用的內存。由於軟引用所指向的對象可能被回收掉,在通過get方法來獲取軟引用所實際指向的對象的時候,總是要檢查該對象是否還存活。
弱引用

弱引用(weak reference)在強度上弱於軟引用,通過類WeakReference來表示。它的作用是引用一個對象,但是並不阻止該對象被回收。如果使用一個強引用的話,只要該引用存在,那麼被引用的對象是不能被回收的。弱引用則沒有這個問題。在垃圾回收器運行的時候,如果一個對象的所有引用都是弱引用的話,該對象會被回收。弱引用的作用在於解決強引用所帶來的對象之間在存活時間上的耦合關系。弱引用最常見的用處是在集合類中,尤其在哈希表中。哈希表的介面允許使用任何Java對象作為鍵來使用。當一個鍵值對被放入到哈希表中之後,哈希表對象本身就有了對這些鍵和值對象的引用。如果這種引用是強引用的話,那麼只要哈希表對象本身還存活,其中所包含的鍵和值對象是不會被回收的。如果某個存活時間很長的哈希表中包含的鍵值對很多,最終就有可能消耗掉JVM中全部的內存。
對於這種情況的解決辦法就是使用弱引用來引用這些對象,這樣哈希表中的鍵和值對象都能被垃圾回收。Java中提供了WeakHashMap來滿足這一常見需求。
幽靈引用

在介紹幽靈引用之前,要先介紹Java提供的對象終止化機制(finalization)。在Object類裡面有個finalize方法,其設計的初衷是在一個對象被真正回收之前,可以用來執行一些清理的工作。因為Java並沒有提供類似C++的析構函數一樣的機制,就通過 finalize方法來實現。但是問題在於垃圾回收器的運行時間是不固定的,所以這些清理工作的實際運行時間也是不能預知的。幽靈引用(phantom reference)可以解決這個問題。在創建幽靈引用PhantomReference的時候必須要指定一個引用隊列。當一個對象的finalize方法已經被調用了之後,這個對象的幽靈引用會被加入到隊列中。通過檢查該隊列裡面的內容就知道一個對象是不是已經准備要被回收了。
幽靈引用及其隊列的使用情況並不多見,主要用來實現比較精細的內存使用控制,這對於移動設備來說是很有意義的。程序可以在確定一個對象要被回收之後,再申請內存創建新的對象。通過這種方式可以使得程序所消耗的內存維持在一個相對較低的數量。

閱讀全文

與java引用被回收相關的資料

熱點內容
為什麼安卓手錶續航久 瀏覽:155
xsmax可以和安卓什麼比 瀏覽:487
dot加密dns 瀏覽:917
java加密和簽名 瀏覽:812
在社旗用哪個app點外賣最好 瀏覽:338
51單片機流水燈編寫 瀏覽:953
手機c語言編譯器ide怎麼用 瀏覽:786
家長有沒有權利命令孩子 瀏覽:876
如何知道伺服器不穩定 瀏覽:933
ai保存pdf設置 瀏覽:102
愛用雲伺服器登錄 瀏覽:104
表情包修復什麼app 瀏覽:415
安全加密檢測落地頁 瀏覽:750
電子電路原理pdf 瀏覽:404
壓縮空氣充氣 瀏覽:320
fpga嵌入式系統設計pdf 瀏覽:81
php中的閉包 瀏覽:151
u盤文件加密工具下載 瀏覽:80
魔獸世界單機命令 瀏覽:532
什麼APP表情包 瀏覽:841