JavaRush /Java Blog /Random-TW /喝咖啡休息#210。您應該了解的 Java 中所有類型的垃圾收集器

喝咖啡休息#210。您應該了解的 Java 中所有類型的垃圾收集器

在 Random-TW 群組發布
來源:Hackernoon 透過這篇文章,您將了解 Java 開發中使用的每種類型的垃圾收集器的優點和缺點。 喝咖啡休息#210。 您應該了解的 Java 中所有類型的垃圾收集器 - 1關於垃圾收集器(GC)的問題幾乎在每次訪談中都能聽到。因此,我決定使用我最喜歡的原則(簡短而簡單)來收集有關它們的所有必要資訊。首先,讓我們從 CG 的目的以及為什麼我們需要多種類型的垃圾收集器開始。在像C這樣的語言中,我們需要在記憶體中儲存物件資訊並編寫大量樣板程式碼來釋放該記憶體。當然,記憶體洩漏在此類程序中很常見。Java 使用垃圾收集器解決記憶體洩漏問題。作為開發人員,您應該知道最好使用哪種垃圾收集器。很大程度取決於程式的運行位置和方式。它可能運行在較弱的硬體上或具有大量對象,或者您的程式必須非常快。根據這些條件,您應該調整垃圾收集器以獲得所需的效能。那麼,讓我們開始吧。

JVM如何處理記憶體

Java虛擬機器(JVM)將記憶體分為兩個區域:堆(儲存應用程式資料)和非堆(儲存程式程式碼和其他資料)。讓我們把注意力轉向堆疊區域。這是我們的程式創建新物件的地方。所有垃圾收集器都基於許多程式使用短暫物件的事實。也就是說,這些物件被創建,然後完成其功能並且不再需要。大多數此類對象。但有些物體的壽命要長得多,甚至可能在整個程序期間都是如此。這就是將物件分為年輕代和老年代的想法產生的地方。我們需要經常檢查年輕一代。事實上,垃圾收集過程分為輕微清理(僅影響年輕一代)和完全清理(可能影響兩代)。請記住,垃圾收集器是一個程式。它需要電腦的時間和資源才能運作。這也影響了我們的應用。它有何影響?例如,為了執行垃圾收集,JVM 會暫停我們的應用程式。這稱為「世界停止」(STW) 暫停。在此期間,所有應用程式執行緒都被掛起。但裡面的應用程式完全不知道這一點。對於應用程式來說,時間是均勻流動的。為什麼情況這麼糟?想像一下,您正在編寫某種交換應用程式或飛機自動駕駛儀應用程式。您的應用程式可能會進入休眠狀態一秒鐘,然後問題的性質可能會發生巨大變化。也就是說,暫停對於每個垃圾收集器來說都是一個重要的參數。垃圾收集器的下一個基本屬性是收集垃圾所花費的總時間與程式總執行時間的關係。這意味著什麼以及為什麼如此重要?我們可以選擇一種具有許多小暫停的演算法,而不是一個大的「Stop-The-World」階段。短暫的休息是更好的選擇,但沒有什麼是免費的。在這種情況下,我們透過增加程式的總執行時間來付費。我們也必須考慮到這一點。下一個參數是硬體資源量。每個收集器都需要記憶體來儲存物件資訊和處理器來執行清理。最後一個參數是速度。垃圾收集效率是指垃圾收集器 (GC) 回收程序不再使用的記憶體的速度和效率。所有這些參數都會影響演算法,演算法可以在消耗最少資源的同時盡快釋放記憶體。讓我們來看看我們可以使用的垃圾收集器。對於面試,您需要了解前五個。另外兩個則困難得多。

序列GC

Serial GC 是 Java 虛擬機器的垃圾收集器,自 Java 誕生以來就一直在使用。它對於堆較小且運行在功能較弱的機器上的程式很有用。此垃圾收集器將堆劃分為多個區域,其中包括 Eden 和 Survivor。Eden 區域是大多數物件最初分配記憶體的池。Survivor 是一個池,包含在 Eden 區域的垃圾回收中倖存下來的物件。當堆填滿時,物件會在 Eden 區和 Survivor 區之間移動。JVM 不斷監視物件向 Survivor 區域的移動,並為此類移動的次數選擇適當的閾值,之後將物件移至 Tenured 區域。當 Tenured 區域中沒有足夠的空間時,完整垃圾收集將接管,對兩代物件進行處理。 這種垃圾收集器的主要優點是其資源需求低,因此低功耗處理器足以執行收集。Serial GC 的主要缺點是垃圾收集期間的長時間暫停,尤其是當涉及大量資料時。

平行CG

平行垃圾收集器(Parallel CG)類似於順序建構子。它包括一些任務的並行處理和自動調整性能設定的能力。平行 GC 是一種基於串行 GC 思想的 Java 虛擬機器垃圾收集器,但增加了平行性和智慧性。如果電腦有多個處理器核心,舊版的 JVM 會自動選擇並行 GC。這裡的堆被劃分為與 Serial GC 中相同的區域 - Eden、Survivor 0、Survivor 1 和 Old Gen (Tenured)。然而,多個執行緒並行參與垃圾收集,收集器可以調整到所需的效能參數。每個收集器線程都有一個需要清除的記憶體區域。並行 GC 還具有旨在實現所需垃圾收集效率的設定。收集器使用先前垃圾收集的統計資料來調整未來收集的效能設定。並行 GC 提供效能參數的自動調整和較低的建置暫停時間,但有一個小缺點,即一些記憶體碎片。它適用於大多數應用程序,但對於更複雜的程序,最好選擇更高級的垃圾收集器實現。 優點:在許多情況下比 Serial GC 更快。具有良好的速度。缺點:消耗更多資源,暫停時間可能很長,但我們可以調整 Stop-The-World 的最大暫停時間。

並發標記清除

並發標記清除 (CMS) 垃圾收集器旨在透過與應用程式執行緒同時運行一些垃圾收集任務來減少最大暫停長度。這種垃圾收集器適合管理記憶體中的大量資料。並發標記清除 (CMS) 是 Java 虛擬機器 (JVM) 中並行 GC 的替代方案。它適用於需要存取多個處理器核心並對 Stop-The-World 暫停敏感的應用程式。CMS 與主程式並行執行垃圾收集步驟,這使得它可以不間斷地運作。它使用與串行和並行收集器相同的記憶體組織,但在運行老年代清除之前不會等待 Tenured 區域被填充。相反,它在後台運行並嘗試保持 Tenured 區域的緊湊。並發標記清除從初始標記階段開始,該階段會短暫停止應用程式的主執行緒並標記可從根存取的所有物件。然後應用程式的主執行緒恢復,CMS 開始搜尋可透過標記根物件的連結存取的所有活動物件。標記完所有存活物件後,收集器會清除多個並行執行緒中死亡物件的記憶體。CMS 的優點之一是它專注於最大限度地減少停機時間,這對於許多應用程式至關重要。然而,它需要犧牲CPU資源和整體頻寬。另外,CMS不會壓縮老年代中的對象,這會導致碎片。由於可能的平行模式故障而導致的長時間暫停可能會令人不愉快(儘管這種情況並不經常發生)。如果有足夠的內存,CMS 可以避免此類暫停。 優點:快。有短暫的「世界靜止」停頓。缺點:消耗較多記憶體;如果記憶體不足,某些停頓可能會很長。如果應用程式創建了很多對象,那就不太好。

垃圾優先

垃圾優先 (G1) 被認為是 CMS 的替代方案,特別是對於在多處理器伺服器上執行並管理大型資料集的伺服器應用程式。G1 垃圾收集器將記憶體轉換為多個同等大小的區域,但巨大區域除外(透過合併常規區域以容納大量物件而建立)。區域不必連續組織,並且可以改變它們的世代隸屬關係。定期對年輕一代進行小型清除,並將物件移動到倖存者區域或將其升級到老一代並將其轉移到終身。僅在需要避免超過所需時間的區域進行清潔。收集者自己預測並選擇垃圾量最多的區域進行清潔。完整掃描使用標記循環來建立與主應用程式並行運行的活動物件清單。標記週期結束後,G1 切換到運行混合清除,這會將較舊的生成區域新增至要清除的年輕生成區域集中。G1 垃圾收集器被認為在預測暫停大小方面比 CMS 收集器更準確,並且可以更好地隨時間分佈垃圾收集,以防止應用程式長時間停機,尤其是在堆大小較大的情況下。它也不像 CMS 收集器那樣產生記憶體碎片。然而,G1收集器需要更多的CPU資源來與主程式並行運行,這降低了應用程式的吞吐量。 優點:比 CMS 更好用。停頓時間較短。缺點:消耗更多的CPU資源。此外,如果我們有許多相當大的物件(超過 500 KB),它會消耗更多內存,因為它將這些物件放在一個區域中(1-32 MB)。

埃普西隆氣相層析儀

Epsilon GC 專為不需要垃圾回收的情況而設計。它不執行垃圾收集,而是使用 TLAB(線程本地分配緩衝區)來分配新物件 - 各個線程從堆中請求的小記憶體緩衝區。不適合緩衝區的巨大物件專門為自己請求記憶體區塊。當 Epsilon GC 耗盡資源時,會產生 OutOfMemoryError 並且進程終止。Epsilon GC 的優點包括較低的資源需求和更快的記憶體分配,適用於在啟動時創建所需的所有物件或運行不使用所有已分配記憶體的短期應用程式的應用程式。Epsilon GC 還可以協助分析其他垃圾收集器添加到您的應用程式中的資源需求。 優點:非常快。缺點:不清除物件:) 接下來的兩個收集器是同類收集器中最先進的,但也是最複雜的。因此,我們將簡要地考慮它們。

中關村

即使在處理海量資料時,ZGC 也能保持亞毫秒的延遲。ZGC 是 Oracle 為 Java 開發的垃圾收集器,旨在處理大型堆(高達 16 TB)時提供高吞吐量和低延遲。ZGC基於虛擬記憶體原理,在垃圾收集過程中使用不同的顏色標記來追蹤物件的狀態。 優點:即使在大型堆疊上,暫停也少於一毫秒,這對於需要較短查詢處理時間的應用程式非常有用。它適用於具有良好吞吐量的非常大的堆。ZGC可以在垃圾收集期間壓縮堆記憶體。缺點:CPU 使用率高且效能要求高,這可能會減慢應用程式的啟動時間。

謝南多厄 G.C.

Shenandoah GC 是另一種垃圾收集器,無論堆大小如何,都會短暫暫停。這個垃圾收集器是由紅帽開發的。它旨在最大限度地減少應用程式在垃圾收集上花費的時間。與 ZGC 一樣,它是一個並行收集器,這意味著它在應用程式運行時運行,從而最大限度地減少暫停。Shenandoah GC 在垃圾收集期間使用「前向指標」來移動物件。它還具有一種稱為“負載屏障去除”的技術來提高性能。 優點:Shenandoah GC 可以實現較短的暫停時間,通常小於 10 毫秒,即使對於大量堆也是如此。良好的吞吐量。缺點:處理器負載高,難以在重負載下運作。

結論

垃圾收集器是程式設計中最困難的任務之一。新的發展正在朝著這個方向不斷進行。雖然程式設計師很少調整 GC,但您仍然需要至少了解垃圾收集工具的工作原理。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION