更新時間:2022-09-05 10:34:01 來源:動力節點 瀏覽3636次
本文檔將解釋什么是 java 中的垃圾收集器以及主要的垃圾收集器類型以及每個垃圾收集器的行為。
Java 是一種面向對象的編程語言,包括Automatic Garbage Collection。Java 會自動分配和取消分配內存,因此程序不會承擔該任務。現在(Java-12),Java 有七種類型的垃圾收集器。
這是最簡單的 GC 實現。它基本上是為單線程環境設計的。此GC垃圾回收實現在運行時凍結所有應用程序線程。它使用單線程進行垃圾收集。因此,在服務器環境等多線程應用程序中使用它并不是一個好主意。
要啟用串行垃圾收集器,我們可以使用以下參數:
java -XX:+UseSerialGC -jar Application.java
并行垃圾收集器也稱為吞吐量收集器。與串行垃圾收集器不同,它使用多個線程進行垃圾收集。與串行垃圾收集器類似,這也會在執行垃圾收集時凍結所有應用程序線程。垃圾收集器最適合那些可以承受應用程序暫停的應用程序。
要啟用并行垃圾收集器,我們可以使用以下參數:
java -XX:+UseParallelGC -jar Application.java
如果我們使用這個GC,我們可以指定最大垃圾收集線程和暫停時間、吞吐量和占用空間(堆大小)
可以使用命令行選項控制垃圾收集器線程的數量
-XX: ParallelGCThreads=<N>
使用命令行選項指定最大暫停時間目標(兩次GC之間的間隔 [以毫秒為單位] )
-XX: MaxGCPauseMillis=<N>
最大吞吐量目標(根據執行垃圾收集所花費的時間與在垃圾收集之外花費的時間來衡量)由命令行選項指定
-XX:GCTimeRatio=<N>
使用選項-Xmx <N>指定最大堆占用空間(程序運行時所需的堆內存量)。
并發標記掃描 (CMS) 垃圾收集器使用多個垃圾收集器線程進行垃圾收集。它掃描堆內存以標記要驅逐的實例,然后掃描標記的實例。它專為喜歡更短的垃圾收集暫停的應用程序而設計,并且可以在應用程序運行時與垃圾收集器共享處理器資源。
CMS 垃圾收集器僅在以下兩種情況下持有所有應用程序線程
在標記老年代空間中的引用對象期間。
堆內存的任何變化與垃圾回收并行
與并行垃圾收集器相比,CMS 收集器使用更多的 CPU 來確保更好的應用程序吞吐量。如果我們可以分配更多的 CPU 以獲得更好的性能,那么 CMS 垃圾收集器是優于并行收集器的首選。
要啟用 CMS 垃圾收集器,我們可以使用以下參數:
java -XX:+USeParNewGC -jar Application.java
G1(垃圾優先)垃圾收集器專為在具有大內存空間的多處理器機器上運行的應用程序而設計。它從JDK7 Update 4和更高版本開始可用。
它將堆內存分成多個區域,并在其中并行收集。G1 也會在回收內存后立即壓縮空閑堆空間。但是 CMS 垃圾收集器會在停止世界 (STW) 情況下壓縮內存。G1收集器將取代CMS收集器,因為它更高效。
在 G1 中收集器包含兩個階段;
打標
掃地
與其他收集器不同,G1收集器將堆劃分為一組大小相等的堆區域,每個區域都是連續的虛擬內存范圍。在執行垃圾回收時,G1顯示了一個并發的全局標記階段,以確定整個堆中對象的活躍度。
標記階段完成后,G1知道哪些區域大部分是空的。它首先在這些區域收集,這通常會產生大量可用空間。這就是為什么這種垃圾收集方法被稱為 Garbage-First 的原因。
要啟用 G1 垃圾收集器,我們可以使用以下參數:
java -XX:+UseG1GC -jar Application.java
Epsilon 是一個不可操作的或被動的垃圾收集器。它為應用程序分配內存,但不收集未使用的對象。當應用程序耗盡 Java 堆時,JVM 將關閉。這意味著 Epsilon 垃圾收集器允許應用程序耗盡內存并崩潰。
此垃圾收集器的目的是測量和管理應用程序性能。活動垃圾收集器是在 JVM 中與您的應用程序一起運行的復雜程序。Epsilon 消除了 GC 對性能的影響。沒有 GC 周期或讀取或寫入障礙。使用 Epsilon GC 時,代碼是獨立運行的。Epsilon 有助于可視化垃圾收集如何影響應用程序的性能以及內存閾值是多少,因為它會在耗盡時顯示。例如,如果我們認為我們的應用程序只需要 1 GB 的內存,我們可以使用 -Xmx1g 運行它并查看行為。如果該內存分配不足,請使用堆轉儲重新運行它。請注意,我們必須啟用此選項才能獲得堆轉儲。
XX:HeapDumpOnOutOfMemoryError
如果我們需要充分利用應用程序的性能,Epsilon 可能是 GC 的最佳選擇。但是我們需要對我們的代碼如何使用內存有一個完整的了解。如果它幾乎不產生垃圾,或者您確切知道它在運行期間使用了多少內存,那么 Epsilon 是一個可行的選擇。
要啟用 Epsilon 垃圾收集器,我們可以使用以下參數:
java -XX:+UseEpsilonGC -jar Application.java
ZGC 并發執行所有昂貴的工作,不會停止應用程序線程的執行超過 10 毫秒,這使其適用于需要低延遲和/或使用非常大堆的應用程序。根據 Oracle 文檔,它可以處理數 TB 的堆。Oracle 在 Java 11 中引入了 ZGC。Z 垃圾收集器在其線程中執行其循環。它平均暫停應用程序 1 毫秒。G1 和 Parallel 收集器平均大約 200 毫秒。
在 Java 12 中,即使 Z 仍處于實驗狀態,Oracle 也添加了性能修復和類卸載。它僅在 64 位 Linux 上可用。但是,ZGC 通過一種稱為指針著色的技術來利用 64 位指針。彩色指針存儲有關堆上對象的額外信息。這是它僅限于 64 位 JVM 的原因之一。
ZGC會嘗試自己設置線程數,通常是對的。但是如果 ZGC 有太多的線程,它會餓死你的應用程序。如果它沒有足夠的,您將創建垃圾比 GC 收集它的速度更快。ZGC 的階段說明了它如何在不影響應用程序內存增長的情況下管理大型堆。
要啟用 Z 垃圾收集器,我們可以使用以下參數:
java -XX:+UseZGC -jar Application.java
Shenandoah 是一個超低暫停時間的垃圾收集器,它通過與正在運行的 Java 程序同時執行更多的垃圾收集工作來減少 GC 暫停時間。CMS 和 G1 都執行活動對象的并發標記。Shenandoah 增加了并發壓縮。
Shenandoah 使用內存區域來管理哪些對象不再使用,哪些對象是活動的并準備好進行壓縮。Shenandoah 還為每個堆對象添加了一個轉發指針,并使用它來控制對對象的訪問。Shenandoah 的設計以并發 CPU 周期和空間換取暫停時間的改進。轉發指針使移動對象變得容易,但激進的移動意味著 Shenandoah 比其他 GC 使用更多的內存并且需要更多的并行工作。但它通過非常短暫的停頓來完成額外的工作。
Shenandoah 在許多小階段處理堆,其中大部分與應用程序并發。這種設計使 GC 可以有效地管理大堆。
Shenandoah 提供與 ZGC 相同的優勢,具有大堆但更多的調整選項。根據您的應用程序的性質,不同的啟發式方法可能非常適合。它的暫停時間可能不如 ZGC 的那么短,但它們更容易預測。
要啟用 Shenandoah 垃圾收集器,我們可以使用以下參數:
java -XX:+UseShenanodoahC -jar Application.java
以上就是關于“7種Java垃圾回收器”的介紹,大家如果對此比較感興趣,想了解更多相關知識,不妨來關注一下動力節點的Java在線學習,技術文檔中的內容從入門到精通,細致全面,很適合沒有基礎的小伙伴學習,希望對大家能夠有所幫助。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習