首頁 > 俗語

JVM垃圾回收調優

作者:由 開源favorer 發表于 俗語日期:2023-02-05

如何解決垃圾回收

在前兩個CHA

T中,我們JVM記憶體的劃分、JVM如何確定一個物件是否為垃圾、垃圾回收演算法、STOP THE WORLD問題和三色標記法,並盤點了各類JVM垃圾收集器,如果對以上內容還不太熟悉的讀者建議翻看小編的前兩篇作品。

本CHAT中,我們將結合前面兩篇的知識,將理論用於實踐,分析和最佳化JVM垃圾回收,側重點在於分析流程、手段和解決辦法。

JVM垃圾回收調優

調優目標

確定目標是行動的第一步,我們在上一個CHAT中講到,評價JVM垃圾回收器有三個指標:記憶體佔用、吞吐量、延遲,並且是一個不可能三角。在實際開展中,記憶體一定是有限的,不可能做到無限大,所以只能是在高吞吐量和低延遲上做取捨了。

那麼,什麼場景下我們會更在意高吞吐量,什麼情況下我們又更在意低延遲呢?一般來講,不直接面向客戶的、非同步的、批次的我們傾向於偏重高吞吐量,因為這是結果最優的方式;而直接面向客戶的、聯機的我們傾向於低延遲,這是客戶體驗和節點防超時的要求。

經典垃圾回收器的搭配使用

垃圾回收器根據回收的堆區域不同,分為青年代垃圾回收器和老年代垃圾回收器,他們的組合使用不是任意的,組合關係見下圖:

JVM垃圾回收調優

(垃圾回收器組合)

考慮到,Serial回收器的效能問題,實際上我們通常選擇是這樣的,

如果是追求高吞吐量,則選擇Parallel Scavenge+Parallel Old組合;如果是追求低延遲,在1。8以後選擇G1,在1。8之前選擇ParNew+CMS組合

調優都可以調什麼

JVM調優我們究竟可以做些什麼呢?第一個就是選擇合適的垃圾回收器(硬體配置常常受限於通用規格和預算,這裡不表);第二個就是設定升級年齡大小;第三個就是堆具體引數設定,包括日誌、各區塊大小等。

前面我們已經講解了根據場景選擇合適的垃圾回收器即回答了第一個調優點。第二個調節點比較考究和複雜,其調整效果取決於青年代和老年代大小、程式物件存活特徵,需要反覆除錯才能找到舒適點。就直接效果來說,數字小一點,會盡早進入老年代,可能青年代導致清理不徹底引發fullGC,數字大一點,可能因為儲存了大量長期消耗不掉的物件,引發OOM。

下面我們介紹一下第三個調優點也就是JVM調優常見引數和基本的監控工具。

JVM常見調優引數

通用GC引數

-Xmn:年輕代大小 -Xms:堆初始大小 -Xmx:堆最大大小 -Xss:棧大小

-XX:+UseTlab:使用tlab,預設開啟,涉及到物件分配問題

-XX:+PrintTlab:列印tlab使用情況

-XX:+TlabSize:設定Tlab大小

-XX:+DisabledExplictGC:java程式碼中的System。gc()不再生效,防止程式碼中誤寫,導致頻繁觸動GC,預設不起用。

-XX:+PrintGC(+PrintGCDetails/+PrintGCTimeStamps)列印GC資訊(列印GC詳細資訊/列印GC執行時間)

-XX:+PrintHeapAtGC列印GC時的堆資訊

-XX:+

PrintGCApplicationConcurrentTime 列印應用程式的時間

-XX:+

PrintGCApplicationStopedTime 列印應用程式暫停時間

-XX:+PrintReferenceGC 列印回收多少種引用型別的引用

-verboss:class 類載入詳細過程

-XX:+PrintVMOptions 列印JVM執行引數

-XX:+PrintFlagsFinal(+PrintFlagsInitial) -version | grep 查詢想要了解的命令,很重要

-X:loggc:/opt/gc/log/path 輸出gc資訊到檔案

-XX:MaxTenuringThreshold 設定gc升到年齡,最大值為15

parallel常用引數

-XX:PreTenureSizeThreshold 多大的物件判定為大物件,直接晉升老年代

-XX:+ParallelGCThreads 用於併發垃圾回收的執行緒

-XX:+UseAdaptiveSizePolicy 自動選擇各區比

CMS常用引數

-XX:+UseConcMarkSweepGC 使用CMS垃圾回收器

-XX:parallelCMSThreads CMS執行緒數量

-XX:CMSInitiatingOccupancyFraction 佔用多少比例的老年代時開始CMS回收,預設值68%,如果頻繁發生serial old,適當調小該比例,降低FGC頻率

-XX:+

UseCMSCompactAtFullCollection 進行壓縮整理

-XX:CMSFullGCBeforeCompaction 多少次FGC以後進行壓縮整理

-XX:+CMSClassUnloadingEnabled 回收永久代

-XX:+

CMSInitiatingPermOccupancyFraction 達到什麼比例時進行永久代回收

GCTimeTatio 設定GC時間佔用程式執行時間的百分比,該引數只能是儘量達到該百分比,不是肯定達到

-XX:MaxGCPauseMills GCt停頓時間,該引數也是儘量達到,而不是肯定達到

G1常用引數

-XX:+UseG1 使用G1垃圾回收器

-XX:MaxGCPauseMills GCt停頓時間,該引數也是儘量達到,G1會調整yong區的塊數來達到這個值

-XX:+G1HeapRegionSize 分割槽大小,範圍為1M~32M,必須是2的n次冪,size越大,GC回收間隔越大,但是GC所用時間越長

G1NewSizePercent 新生代所佔最小比例,預設5%

G1MaxNewSizePercent 新生代所佔最大比例,預設60%

GCTimeRatio GC時間比例,此值為建議值,G1會調整堆大小來儘量達到這個值

ConcGCThreads GC執行緒數量

InitiatingHeapOccupancyPercent 啟動G1的堆空間佔用比例

JVM分析基礎工具

jinfo pid

,可以檢視當前進行虛擬機器的相關資訊列舉出來

JVM垃圾回收調優

(jinfo 命令)

jstat -gc pid ms

,多長毫秒列印一次gc資訊,列印資訊如下,裡面包含gc測試,年輕代/老年代gc資訊等:

JVM垃圾回收調優

(jstat 命令)

jmap -histo pid | head -20

,查詢當前程序堆中的物件資訊,加上管道符後面的資訊以後,代表查詢物件數量最多的20個:

JVM垃圾回收調優

(jmap 命令)

以上就是本CHAT的內容,關注小編,更多精彩