JavaRush /Java Blog /Random-TW /Java 中的垃圾回收器
Diana
等級 41

Java 中的垃圾回收器

在 Random-TW 群組發布

垃圾收集器(記憶體回收器)的行為線

Java 程式設計師不需要監視記憶體分配,因為垃圾收集器會自動管理記憶體。垃圾收集器由 Java 虛擬機器 (JVM) 運行。垃圾收集器是一個低優先權進程,它定期運行並釋放不再需要的物件使用的記憶體。不同的 JVM 有不同的垃圾收集演算法。使用了多種演算法,例如:引用計數演算法或標記和抓取演算法。垃圾收集 - 1

在 Java 中運行垃圾收集器

當可用記憶體較低時,JVM 通常會執行垃圾收集器。但垃圾收集器的運作並不能保證總是有足夠的空閒記憶體。如果恢復後仍然沒有足夠的內存,JVM 會拋出 OutOfMemoryError 異常。請注意,JVM 在拋出異常之前必須至少執行一次垃圾收集器。您可以請求垃圾收集器在 Java 中運行,但不能強制執行此操作。

請求運行垃圾收集器

若要發出請求,您可以呼叫下列方法之一:
System.gc()
Runtime.getRuntime().gc()

適合運行垃圾收集器

當物件不再可供活動串流使用時,必須將其丟棄。一個物體可能會在不同的情況下被處置:
  • 如果引用某個物件的參考類型變數被設定為“0”,且沒有其他引用對該物件進行處理,則必須釋放該物件。
  • 如果建立引用一個對象的參考類型變數來引用另一個對象,並且沒有其他引用對該對象進行處理,則必須釋放該對象。
  • 當方法退出時,在方法中本地建立的物件將被丟棄,除非它們是從該方法導出的(即作為異常返回或拋出)。
  • 如果沒有一個物件可供活動線程使用,則相互引用的物件可能會被處置。
讓我們來看一個例子:
public class TestGC
  {
    public static void main(String [] args)
    {
      Object o1 = new Integer(3);               // Line 1
      Object o2 = new String("Tutorial");       // Line 2
      o1 = o2;                                  // Line 3
      o2 = null;                                // Line 4
      // Rest of the code here
    }
  }
在此範例中Integer,最初由 o1 引用的物件(整數)可以在第 3 行之後處理,因為 o1 現在引用該物件String(字串)。即使創建 o2 來引用 null,該物件String(字串)也是不可回收的,因為 o1 引用了它。

最終確定

finalize()Java 技術可讓您在垃圾收集器從記憶體中檢索物件之前使用方法(finalize) 進行必要的清理。當垃圾收集器確定不再有對該物件的參考時,垃圾收集器會對該物件呼叫此方法。這是在 class 中描述的Object,這意味著它被所有類別繼承。子類別重寫該方法finalize()以將其自身從系統資源中釋放出來或進行另一次清理:
protected void finalize() throws Throwable
如果方法拋出未註冊的異常finalize(),則該異常將被忽略並且該物件的終結將停止。此方法finalize()在物件的生命週期內只會被呼叫一次。可以對finalize()任何物體使用某種方法來保護其免遭處置。但在這種情況下,垃圾收集器不再finalize()為此物件啟動。finalize()在物件被垃圾收集之前,該方法始終會被呼叫一次。然而,對於給定對象,該方法finalize()可能不會在其存在的整個持續時間內被激活,因為它可能不會受到處置。

概括

在本節中,我們研究了垃圾收集過程,這是 Java 語言中的記憶體管理技術。不能強制垃圾收集。我們了解了使物件符合回收條件的不同方法,並了解了finalize()在垃圾收集器回收物件之前呼叫該方法。

鍛鍊

問: 第 7 行之後有多少物品會被處置?
public class TutorialGC
  {
    public static void main(String [] args)
    {
      Object a = new Integer(100);  // Line1
      Object b = new Long(100);     // Line2
      Object c = new String("100"); // Line3
      a = null;                     // Line4
      a = c;                        // Line5
      c = b;                        // Line6
      b = a;                        // Line7
      // Rest of the code here
    }
  }
答案選項: A. 0 B. 1 C. 2 D. 3 E. 程式碼無法編譯 正確選項: B 說明:在第 1、2、3 行建立的三個物件中,只有該物件Integer必須在第7 行結尾.最初引用對象的變數引用 a在第 5 行Integer引用了該對象。因此,必須在第 5 行之後處理該對象,因為沒有引用它的變數。變數和引用第6行和第7行中的對象和對象,因此它們是不可回收的。 StringIntegerbcStringLong
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION