日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

G1收集器调优

發布時間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 G1收集器调优 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇針對官網G1性能調優進行翻譯,并補充部分參數解釋。本文可作參考模板亦可為調優理論依據。

另外我整理了一套 G1垃圾收集調優-精簡版 。

目錄

G1 的一般建議

從其他收集器轉移到 G1

提高 G1 性能

觀察Full GC收集

巨大的對象碎片

調整延遲

異常系統或實時使用

引用對象處理時間太長

混合收集耗時太長

高更新 RS 和掃描 RS 次數

調整吞吐量

調整堆大小

可調默認值


G1 的一般建議

一般建議是使用 G1 及其默認設置,最終給它一個不同的暫停時間目標,并根據需要設置最大 Java 堆大小?-Xmx

G1 默認值的平衡與其他收集器不同。G1 在默認配置中的目標既不是最大吞吐量也不是最低延遲,而是在高吞吐量下提供相對較小、統一的暫停。然而,G1 增量回收堆空間的機制和暫停時間控制在應用程序線程和空間回收效率方面都會產生一些開銷。

如果您更喜歡高吞吐量,那么通過使用-XX:MaxGCPauseMillis?或提供更大的堆來放松暫停時間目標。如果延遲是主要要求,則修改暫停時間目標。避免使用-Xmn,-XX:NewRatio等選項將年輕代大小限制為特定值,因為年輕代大小是 G1 允許其滿足暫停時間的主要手段。將年輕代大小設置為單個值會覆蓋并實際上禁用暫停時間控制。

從其他收集器轉移到 G1

通常,當從其他收集器(尤其是并發標記清除收集器)移動到 G1 時,首先刪除所有影響垃圾收集的選項,并且僅使用-Xmx和 可選設置暫停時間目標和總體堆大小-Xms。

許多對其他收集器以某種特定方式響應有用的選項要么根本沒有影響,要么甚至降低吞吐量和滿足暫停時間目標的可能性。一個例子可能是設置年輕代大小,完全阻止 G1 調整年輕代大小以滿足暫停時間目標。

提高 G1 性能

G1 旨在提供良好的整體性能,而無需指定其他選項。但是,在某些情況下,它們的默認啟發式方法或默認配置會提供次優結果。本節提供了一些有關在這些情況下診斷和改進的指南。本指南僅描述了 G1 在給定一組應用程序時,在選定指標中提高垃圾收集器性能的可能性。在個案的基礎上,應用程序級優化可能比嘗試調整 VM 以提高性能更有效,例如,通過完全避免一些壽命較短的對象來避免一些有問題的情況。

出于診斷目的,G1 提供了全面的日志記錄。一個好的開始是使用該-Xlog:gc*=debug選項,然后在必要時從該選項中細化輸出。該日志提供有關垃圾收集活動暫停期間和之外的詳細概述。這包括收集的類型和在暫停的特定階段花費的時間細分。

以下小節探討了一些常見的性能問題。

觀察Full GC收集

一次全堆垃圾回收(Full GC)通常非常耗時。老年代堆占用過高導致的Full GC可以通過在日志中找到Pause Full (Allocation Failure)字樣來檢測。Full GC 之前通常是遇到to-space exhausted標記指示的疏散失敗的垃圾收集。

發生 Full GC 的原因是應用程序分配了太多無法快速回收的對象。通常并發標記無法及時完成以啟動空間回收階段。由于分配了許多龐大的對象,因此可能會遇到 Full GC。由于這些對象在 G1 中的分配方式,它們可能占用比預期更多的內存。

目標應該是確保并發標記按時完成。這可以通過降低老年代的分配率來實現,或者給并發標記更多的時間來完成。

G1 為您提供了多種選項來更好地處理這種情況:

  • 您可以使用gc+heap=info日志記錄來確定 Java 堆上的大型對象占用的區域數量?。Y在“?Humongous regions:?X->Y”行中給出了巨大對象占據的區域數量。如果該數字與舊區域的數量相比較高,則最好的選擇是嘗試減少此對象數量。您可以通過增加區域來實現此目的size 使用?-XX:G1HeapRegionSize選項。當前選擇的堆區域大小打印在日志的開頭。
  • 增加 Java 堆的大小。這通常會增加標記必須完成的時間量。
  • 通過-XX:ConcGCThreads顯式設置增加并發標記線程的數量。
  • 強制 G1 提前開始標記。G1 根據早期的應用程序行為自動確定初始堆占用百分比 (IHOP) 閾值。如果應用程序行為發生變化,這些預測可能是錯誤的。有兩個選項:下,用于當通過增加通過修改自適應IHOP計算中使用的緩沖液啟動空間回收所述目標占用-XX:G1ReservePercent;?或者,通過使用-XX:-G1UseAdaptiveIHOP?和手動設置來禁用 IHOP 的自適應計算?-XX:InitiatingHeapOccupancyPercent

除了完整 GC 的分配失敗之外的其他原因通常表明應用程序或某些外部工具導致完整堆收集。如果原因是?System.gc(),并且無法修改應用程序源,則可以通過使用?-XX:+ExplicitGCInvokesConcurrent或讓 VM 完全忽略它們來減輕 Full GC 的影響-XX:+DisableExplicitGC。外部工具可能仍會強制執行 Full GC;只有不請求它們才能刪除它們。

巨大的對象碎片

由于需要為它們找到一組連續的區域,因此可能會在所有 Java 堆內存耗盡之前發生 Full GC。在這種情況下,潛在的選項是通過使用選項?-XX:G1HeapRegionSize?來減少巨大對象的數量或增加堆的大小來增加堆區域的大小。在極端情況下,即使可用內存另有指示,也可能沒有足夠的連續空間可供 G1 分配對象。如果 Full GC 無法回收足夠的連續空間,這將導致 VM 退出。因此,除了減少前面提到的龐大對象分配的數量或增加堆外,別無選擇。

調整延遲

本節討論在常見延遲問題(即暫停時間太長)的情況下改進 G1 行為的提示。

異常系統或實時使用

對于每次垃圾收集暫停,gc+cpu=info日志輸出都包含一行信息,其中包含來自操作系統的信息,并詳細說明暫停時間已花費的時間。這種輸出的一個例子是User=0.19s Sys=0.00s Real=0.01s.

用戶時間是花在 VM 代碼上的時間,?system time?是在操作系統中花費的時間,以及?real time是暫停期間經過的絕對時間量。如果系統時間相對較長,那么最常見的原因是環境。

高系統時間的常見已知問題有:

  • VM 從操作系統內存中分配或返還內存可能會導致不必要的延遲。通過使用選項-Xms和將最小和最大堆大小設置為相同的值來避免延遲?-Xmx,并使用預接觸所有內存-XX:+AlwaysPreTouch來將此工作移至 VM 啟動階段。
  • 特別是在 Linux 中,通過透明大頁面 (THP)功能將小頁面合并為大頁面往往會導致隨機進程停止,而不僅僅是在暫停期間。由于 VM 分配和維護大量內存,因此 VM 將成為長時間停滯的進程的風險高于平常。有關如何禁用透明大頁面功能的信息,請參閱操作系統的文檔。
  • 由于某些后臺任務間歇性地占用了寫入日志的硬盤的所有 I/O 帶寬,因此寫入日志輸出可能會停止一段時間。考慮為您的日志或其他一些存儲使用單獨的磁盤,例如內存支持的文件系統以避免這種情況。

另一種需要注意的情況是實時時間遠大于其他情況的總和,這可能表明 VM 在可能過載的機器上沒有獲得足夠的 CPU 時間。

引用對象處理時間太長

有關處理參考對象所需時間的信息顯示在參考處理階段。在引用處理階段,G1根據特定類型的引用對象的要求更新引用對象的引用。默認情況下,G1嘗試使用以下啟發式方法并行化引用處理的子階段:對于每個-XX:ReferencesPerThread引用對象啟動一個單獨的線程,由-XX:ParallelGCThreads中的值限定。可以通過將-XX:ReferencesPerThread設置為0來禁用這種啟發式,默認情況下使用所有可用的線程,或者通過-XX:-ParallelRefProcEnabled完全禁用并行化。

Young-Only 階段的 Young-Only 集合耗時太長

正常的年輕集合,一般來說,任何年輕的集合所花費的時間大致與年輕代的大小成正比,或者更具體地說,集合集中需要復制的活動對象的數量。如果Evacuate Collection Set階段花費的時間太長,尤其是Object Copy子階段,請減少-XX:G1NewSizePercent。這減少了年輕代的最小大小,允許可能更短的暫停。

如果應用程序性能,特別是在集合中存活的對象數量突然發生變化,則可能會出現與年輕代大小有關的另一個問題。這可能會導致垃圾收集暫停時間出現峰值。使用 減少最大年輕代大小可能會很有用-XX:G1MaxNewSizePercent。這限制了年輕代的最大大小以及暫停期間需要處理的對象數量。

混合收集耗時太長

混合收集用于回收老年代的空間。混合收集包含年輕代和年老代區域。您可以通過啟用gc+ergo+cset=trace日志輸出來獲取有關年輕代或年老代區域的疏散時間對暫停時間的信息。分別查看年輕代和年老代區域的預測年輕區域時間和預測年老區域時間。

如果預測的年輕區域時間太長,請參上面的"Young-Only階段的Young_Only集合耗時太長"以獲取選項。否則,為了減少老年代區域對暫停時間的處理,G1 提供了三個選項:

  • 通過增加-XX:G1MixedGCCountTarget?=8(默認) 反復執行混合回收8次,每次回收受MaxGCPauseMillis的影響可能一次性回收不了所有垃圾,增加次數才能回收的更徹底。如果值設置的過小則每次回收的STW時間會延長。

  • -XX:G1MixedGCLiveThresholdPercent?=85(默認) 若要回收的region區存活的對象空間占用達到85%時不去回收此空間。

  • 提前停止老年代空間回收,這樣 G1 就不會收集那么多的高占用區域。在這種情況下,增加?
    -XX:G1HeapWastePercent?=5(默認) 混合回收整理出來的空閑空間占heap的5%時,結果老年代的回收

請注意,最后兩個選項減少了可以為當前空間回收階段回收空間的收集集候選區域的數量。這可能意味著 G1 可能無法在老年代回收足夠的空間來持續運行。然而,稍后的空間回收階段可能能夠對它們進行垃圾收集。

高更新 RS 和掃描 RS 次數

為了使 G1 能夠疏散單個老年代區域,G1 跟蹤跨區域引用的位置,即從一個區域指向另一個區域的引用。指向給定區域的跨區域引用集稱為該區域的記憶集。移動區域的內容時,必須更新記住的集合。區域記憶集的維護大多是并發的。出于性能目的,當應用程序在兩個對象之間安裝新的跨區域引用時,G1 不會立即更新區域的記住集。記住的集合更新請求被延遲和批處理以提高效率。

G1 需要完整的記憶集進行垃圾收集,因此垃圾收集的更新 RS階段處理任何未完成的記憶集更新請求。該掃描RS在記憶組對象引用階段的搜索,移動區域中的內容,然后更新到新的位置,這些對象的引用。根據應用的不同,這兩個階段可能需要很長時間。

使用該選項調整堆區域的大小?-XX:G1HeapRegionSize會影響跨區域引用的數量以及記憶集的大小。處理區域的記住集合可能是垃圾收集工作的重要組成部分,因此這對可實現的最大暫停時間有直接影響。較大的區域往往具有較少的跨區域引用,因此處理它們所花費的相對工作量會減少,但同時,較大的區域可能意味著每個區域要疏散更多的活動對象,從而增加了其他階段的時間。

G1 嘗試調度記憶集更新的并發處理,以便更新 RS 階段占用大約-XX:G1RSetUpdatingPauseTimePercent允許的最大暫停時間的百分比。通過減小這個值,G1 通常會同時執行更多的記憶集更新工作。

偽高更新RS時間與應用程序分配大對象的結合可能是由優化引起的。什么優化?嘗試通過批處理來減少并發記住的集更新工作。
如果創建此類批處理的應用程序恰好發生在垃圾收集之前,那么垃圾收集必須在暫停的Update RS時間部分處理所有這些工作。
使用-XX:-ReduceInitialCardMarks禁用此行為并可能避免這些情況。

掃描 RS 時間也由 G1 執行的壓縮量決定,以保持記住的設置存儲大小較低。記住的集合存儲在內存中越緊湊,在垃圾回收期間檢索存儲的值所需的時間就越多。G1 自動執行這種壓縮,稱為記憶集粗化,同時根據該區域記憶集的當前大小更新記憶集。特別是在最高壓縮級別下,檢索實際數據可能會非常緩慢。-XX:G1SummarizeRSetStatsPeriod與?gc+remset=trace級別記錄結合的選項顯示是否發生這種粗化。如果是這樣,則Before GC Summary部分X?中的行Did <X> coarsenings中的 將顯示高值。這-XX:G1RSetRegionEntries可以顯著增加選項以減少這些粗化的數量。避免在生產環境中使用這種詳細的記住設置日志,因為收集這些數據可能需要大量時間。

調整吞吐量

G1 的默認策略試圖在吞吐量和延遲之間保持平衡;但是,在某些情況下需要更高的吞吐量。除了如前幾節所述減少總體停頓時間外,還可以減少停頓的頻率。主要思想是通過使用增加最大暫停時間-XX:MaxGCPauseMillis。代大小啟發式會自動適應年輕代的大小,這直接決定了暫停的頻率。如果這不會導致預期的行為,特別是在空間回收階段,增加最小年輕代大小?-XX:G1NewSizePercent將迫使 G1 這樣做。

在某些情況下,-XX:G1MaxNewSizePercent允許的最大年輕代大小可能會通過限制年輕代大小來限制吞吐量。這可以通過查看gc+heap=info日志記錄的區域摘要輸出來診斷。在這種情況下,伊甸園區域和幸存者區域的組合百分比接近區域-XX:G1MaxNewSizePercent總數的百分比。-XX:G1MaxNewSizePercent在這種情況下考慮增加。

增加吞吐量的另一個選擇是嘗試減少并發工作量,特別是并發記憶集更新通常需要大量 CPU 資源。增加?-XX:G1RSetUpdatingPauseTimePercent將工作從并發操作轉移到垃圾收集暫停。在最壞的情況下,可以通過設置禁用并發記住的集合更新-XX:-G1UseAdaptiveConcRefinement?-XX:G1ConcRefinementGreenZone=2G?-XX:G1ConcRefinementThreads=0。這主要是禁用此機制并將所有記住的集合更新工作移動到下一個垃圾收集暫停。

通過 using 啟用大頁面的使用-XX:+UseLargePages也可以提高吞吐量。有關如何設置大頁面的信息,請參閱操作系統文檔。

您可以通過禁用它來最小化堆大小調整工作;將選項-Xms?和-Xmx?設置為相同的值。此外,您可以使用-XX:+AlwaysPreTouch將操作系統工作移回虛擬內存與物理內存到 VM 啟動時。為了使暫停時間更加一致,這兩種措施都是特別需要的。

調整堆大小

與其他收集器一樣,G1 旨在調整堆大小,以便垃圾收集所花費的時間低于由-XX:GCTimeRatio選項確定的比率。調整此選項以使 G1 滿足您的要求。

可調默認值

本節介紹有關本主題中介紹的命令行選項的默認值和一些附加信息。

選項和默認值描述

-XX:+G1UseAdaptiveConcRefinement

-XX:G1ConcRefinementGreenZone=<ergo>

-XX:G1ConcRefinementYellowZone=<ergo>

-XX:G1ConcRefinementRedZone=<ergo>

-XX:G1ConcRefinementThreads=<ergo>

并發記憶集更新(細化)使用這些選項來控制并發細化線程的工作分配。G1 為這些選項選擇符合人體工程學的值,以便-XX:G1RSetUpdatingPauseTimePercent在垃圾收集暫停中花費時間來處理任何剩余的工作,并根據需要自適應地調整它們。請謹慎更改,因為這可能會導致非常長的停頓。

-XX:+ReduceInitialCardMarks

這將用于初始對象分配的并發記憶集更新(細化)工作批處理在一起。

-XX:+ParallelRefProcEnabled

-XX:ReferencesPerThread=1000

-XX:ReferencesPerThread確定并行度:對于每N 個參考對象,一個線程將參與參考處理的子階段,受限于-XX:ParallelGCThreads。值 0 表示-XX:ParallelGCThreads將始終使用值所指示的最大線程數。?

這決定了是否處理?java.lang.Ref.*?實例應該由多個線程并行完成。

-XX:G1RSetUpdatingPauseTimePercent=10?

這決定了 G1 在更新 RS 階段應該花費的總垃圾收集時間的百分比來更新任何剩余的記住集。G1 使用此設置控制并發記住集更新的數量。

-XX:G1SummarizeRSetStatsPeriod=0?

這是 G1 在許多 GC 中生成記住的集合摘要報告的時期。將此設置為零以禁用。生成記住的集合摘要報告是一項代價高昂的操作,因此應該僅在必要時使用它,并且具有相當高的價值。使用?gc+remset=trace打印任何東西。

-XX:GCTimeRatio=12?

這是應該用于垃圾收集而不是應用程序的目標時間比率的除數。確定在增加堆之前可用于垃圾收集的目標時間比例的實際公式是?1 / (1 + GCTimeRatio)。這個默認值導致目標有大約 8% 的時間花在垃圾收集上。

-XX:G1PeriodicGCInterval=0

檢查 G1 是否應觸發定期垃圾收集的時間間隔(以毫秒為單位)。設置為零以禁用。

-XX:+G1PeriodicGCInvokesConcurrent

如果設置,定期垃圾回收會觸發并發標記或繼續現有的回收周期,否則會觸發 Full GC。

-XX:G1PeriodicGCSystemLoadThreshold=0.0主機?getloadavg()調用返回的當前系統負載閾值,以確定是否應觸發定期垃圾收集。當前系統負載高于此值會阻止定期垃圾回收。零值表示禁用此閾值檢查。

注:<ergo>?意味著實際值是根據環境根據人體工程學確定的。

總結

以上是生活随笔為你收集整理的G1收集器调优的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。