[英]Objects eligible for garbage collection
這個問題來自Kathy Sierra SCJP 1.6 。 有多少個對象符合垃圾收集的條件?
根據Kathy Sierra的回答,它是C
這意味着兩個對象有資格進行垃圾回收。 我給出了答案的解釋。 但為什么c3
不符合垃圾收集 (GC)的條件?
class CardBoard {
Short story = 200;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// Do stuff
} }
何時達到了這些// Do stuff
,有多少對象符合GC條件?
回答:
Short
包裝器對象,該對象也符合條件。 讓我們逐行打破這個:
CardBoard c1 = new CardBoard();
我們現在有兩個對象, CardBoard
c1
指向和Short
c1.story
。 對於GC而言,兩者都不可用,因為CardBoard
c1
點和Short
CardBoard
點的story
變量...
CardBoard c2 = new CardBoard();
與上面類似,我們現在有四個對象,其中沒有一個可用於GC。
CardBoard c3 = c1.go(c2);
我們調用c1
指向的CardBoard上的方法,傳遞c2
的值,這是對CardBoard
對象的引用。 我們使參數為空,但Java是按值傳遞的,這意味着c2
變量本身不受影響。 然后我們返回nullled參數。 c3
為null
, c1
和c2
不受影響。 我們仍然有4個對象,其中沒有一個可以GC。
c1 = null;
我們null c1
。 c1
之前指向的CardBoard
對象沒有指向它的任何東西,它可以是GC'd。 因為CardBoard
對象中的story
變量是指向Short
的唯一內容,並且因為該CardBoard
對象符合GC的條件,所以Short
也有資格獲得GC。 這給了我們4個對象,其中2個可以是GC'd。 符合GC條件的對象是以前由c1
和c1.story
引用的c1.story
。
c3
指向的任何對象都不存在。 構造函數只被調用兩次,兩個對象,每個對象由c1
和c2
指向。 c3
只是一個引用,除了空指針之外從未分配過任何東西。
當前指向null的引用c3
將不會超出范圍並從堆棧中刪除,直到超過main方法結束時的右括號。
最初分配給c1
的對象無法訪問,因為c1
引用設置為null,但c2
引用尚未更改,因此分配給它的對象仍可通過c2
引用從此作用域訪問。
c3
為null
,因此顯然沒有Object符合垃圾回收的條件。
請注意,只創建了兩個CardBoard
對象,這兩個在這些行上:
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
在參考雜耍之后,其中只有一個沒有參考。
正式答案是我們不知道的。 我們不知道的原因是這一行:
Short story = 200;
這將編譯為以下字節代碼:
CardBoard();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: sipush 200
8: invokestatic #2 // Method java/lang/Short.valueOf:(S)Ljava/lang/Short;
11: putfield #3 // Field story:Ljava/lang/Short;
14: return
第8行是關鍵, Short.valueOf()
,它返回原始200
的盒裝等價物。 讓我們看一下Short.valueOf()
的Javadoc:
此方法將始終緩存-128到127(包括端點)范圍內的值,並可以緩存此范圍之外的其他值。
200超出“必須緩存”范圍,因此它屬於“可以緩存”。 如果它被緩存,則當包含CardBoard
實例時, story
的值不適用於GC。 如果沒有緩存, story
將無法訪問,因此GCed。
為了使問題明確(並且建議的答案正確),代碼應該像這樣修改:
Short story = new Short(200);
更新:用於Short.valueOf()
的1.6 Javadoc比我引用的1.8版本更加神秘,但同樣的邏輯適用:沒有辦法通過查看代碼來判斷Short
的新實例或緩存實例是否會被退回
如果您注意到代碼中只創建了兩個對象。 c3永遠不會初始化為對象,它是一個空引用。 因此,只有一個“對象”符合垃圾收集條件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.