簡體   English   中英

符合垃圾收集條件的對象

[英]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條件?

  • 答:0
  • B:1
  • C:2
  • D:編譯失敗
  • E:不可能知道
  • F:運行時拋出異常

回答:

  • C是對的。 只有一個CardBoard對象(c1)符合條件,但它具有相關的Short包裝器對象,該對象也符合條件。
  • 基於以上原因,A,B,D,E和F不正確。 (目標7.4)

讓我們逐行打破這個:

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參數。 c3nullc1c2不受影響。 我們仍然有4個對象,其中沒有一個可以GC。

c1 = null;

我們null c1 c1之前指向的CardBoard對象沒有指向它的任何東西,它可以是GC'd。 因為CardBoard對象中的story變量是指向Short的唯一內容,並且因為該CardBoard對象符合GC的條件,所以Short也有資格獲得GC。 這給了我們4個對象,其中2個可以是GC'd。 符合GC條件的對象是以前由c1c1.story引用的c1.story

c3指向的任何對象都不存在。 構造函數只被調用兩次,兩個對象,每個對象由c1c2指向。 c3只是一個引用,除了空指針之外從未分配過任何東西。

當前指向null的引用c3將不會超出范圍並從堆棧中刪除,直到超過main方法結束時的右括號。

最初分配給c1的對象無法訪問,因為c1引用設置為null,但c2引用尚未更改,因此分配給它的對象仍可通過c2引用從此作用域訪問。

c3null ,因此顯然沒有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM