JVM調(diào)優(yōu)

何時(shí)進(jìn)行JVM調(diào)優(yōu)

  • Heap內(nèi)存(老年代)持續(xù)上漲達(dá)到設(shè)置的最大內(nèi)存值邀摆;
  • Full GC 次數(shù)頻繁;
  • GC 停頓時(shí)間過長(超過1秒);
  • 應(yīng)用出現(xiàn)OutOfMemory 等內(nèi)存異常;
  • 應(yīng)用中有使用本地緩存且占用大量內(nèi)存空間;
  • 系統(tǒng)吞吐量與響應(yīng)性能不高或下降击蹲。

JVM調(diào)優(yōu)目標(biāo)

調(diào)優(yōu)的最終目的都是為了令應(yīng)用程序使用最小的硬件消耗來承載更大的吞吐。jvm調(diào)優(yōu)主要是針對(duì)垃圾收集器的收集性能優(yōu)化婉宰,令運(yùn)行在虛擬機(jī)上的應(yīng)用能夠使用更少的內(nèi)存以及延遲獲取更大的吞吐量歌豺。

  • 延遲:GC低停頓和GC低頻率;
  • 低內(nèi)存占用心包;
  • 高吞吐量;

吞吐量:重要指標(biāo)之一类咧,是指不考慮垃圾收集引起的停頓時(shí)間或內(nèi)存消耗,垃圾收集器能支撐應(yīng)用達(dá)到的最高性能指標(biāo)。

延遲:其度量標(biāo)準(zhǔn)是縮短由于垃圾啊收集引起的停頓時(shí)間或者完全消除因垃圾收集所引起的停頓轮听,避免應(yīng)用運(yùn)行時(shí)發(fā)生抖動(dòng)骗露。

內(nèi)存占用:垃圾收集器流暢運(yùn)行所需要 的內(nèi)存數(shù)量。

其中血巍,任何一個(gè)屬性性能的提高萧锉,幾乎都是以犧牲其他屬性性能的損為代價(jià)的,不可兼得述寡。具體根據(jù)在業(yè)務(wù)中的重要性確定柿隙。

JVM調(diào)優(yōu)量化目標(biāo)

  • Heap 內(nèi)存使用率 <= 70%;
  • Old generation內(nèi)存使用率<= 70%;
  • avgpause <= 1秒;
  • Full gc 次數(shù)0 或 avg pause interval >= 24小時(shí) ;

JVM調(diào)優(yōu)的步驟

一般情況下,JVM調(diào)優(yōu)可通過以下步驟進(jìn)行:

  • 分析GC日志及dump文件鲫凶,判斷是否需要優(yōu)化禀崖,確定瓶頸問題點(diǎn);
  • 確定JVM調(diào)優(yōu)量化目標(biāo)螟炫;
  • 確定JVM調(diào)優(yōu)參數(shù)(根據(jù)歷史JVM參數(shù)來調(diào)整)波附;
  • 依次調(diào)優(yōu)內(nèi)存、延遲昼钻、吞吐量等指標(biāo)掸屡;
  • 對(duì)比觀察調(diào)優(yōu)前后的差異;
  • 不斷的分析和調(diào)整然评,直到找到合適的JVM參數(shù)配置仅财;
  • 找到最合適的參數(shù),將這些參數(shù)應(yīng)用到所有服務(wù)器碗淌,并進(jìn)行后續(xù)跟蹤盏求。

以上操作步驟中,某些步驟是需要多次不斷迭代完成的亿眠。一般是從滿足程序的內(nèi)存使用需求開始的碎罚,之后是時(shí)間延遲的要求,最后才是吞吐量的要求缕探,要基于這個(gè)步驟來不斷優(yōu)化魂莫,每一個(gè)步驟都是進(jìn)行下一步的基礎(chǔ)还蹲,不可逆行之爹耗。

JVM參數(shù)

-XX 參數(shù)被稱為不穩(wěn)定參數(shù),此類參數(shù)的設(shè)置很容易引起JVM 性能上的差異谜喊,使JVM存在極大的不穩(wěn)定性潭兽。如果此類參數(shù)設(shè)置合理將大大提高JVM的性能及穩(wěn)定性。

不穩(wěn)定參數(shù)語法規(guī)則包含以下內(nèi)容斗遏。

布爾類型參數(shù)值:

  • -XX:+:'+'表示啟用該選項(xiàng)
  • -XX:-:'-'表示關(guān)閉該選項(xiàng)

數(shù)字類型參數(shù)值:

  • -XX:=

字符串類型參數(shù)值:

  • -XX:=

JVM參數(shù)解析及調(diào)優(yōu)

比如以下參數(shù)示例:

-Xmx4g –Xms4g –Xmn1200m –Xss512k -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:PermSize=100m -XX:MaxPermSize=256m -XX:MaxTenuringThreshold=15

上面為Java7及以前版本的示例山卦,在Java8中永久代的參數(shù)-XX:PermSize和-XX:MaxPermSize已經(jīng)失效。這在前面章節(jié)中已經(jīng)講到诵次。

參數(shù)解析:

  • -Xmx4g:堆內(nèi)存最大值為4GB账蓉。
  • -Xms4g:初始化堆內(nèi)存大小為4GB枚碗。
  • -Xmn1200m:設(shè)置年輕代大小為1200MB。增大年輕代后铸本,將會(huì)減小年老代大小肮雨。此值對(duì)系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)堆的3/8箱玷。
  • -Xss512k:設(shè)置每個(gè)線程的堆棧大小怨规。JDK5.0以后每個(gè)線程堆棧大小為1MB,以前每個(gè)線程堆棧大小為256K锡足。應(yīng)根據(jù)應(yīng)用線程所需內(nèi)存大小進(jìn)行調(diào)整波丰。在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程舶得。但是操作系統(tǒng)對(duì)一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的掰烟,不能無限生成,經(jīng)驗(yàn)值在3000~5000左右沐批。
  • -XX:NewRatio=4:設(shè)置年輕代(包括Eden和兩個(gè)Survivor區(qū))與年老代的比值(除去持久代)媚赖。設(shè)置為4,則年輕代與年老代所占比值為1:4珠插,年輕代占整個(gè)堆棧的1/5
  • -XX:SurvivorRatio=8:設(shè)置年輕代中Eden區(qū)與Survivor區(qū)的大小比值惧磺。設(shè)置為8,則兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:8捻撑,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/10
  • -XX:PermSize=100m:初始化永久代大小為100MB磨隘。
  • -XX:MaxPermSize=256m:設(shè)置持久代大小為256MB。
  • -XX:MaxTenuringThreshold=15:設(shè)置垃圾最大年齡顾患。如果設(shè)置為0的話番捂,則年輕代對(duì)象不經(jīng)過Survivor區(qū),直接進(jìn)入年老代江解。對(duì)于年老代比較多的應(yīng)用设预,可以提高效率。如果將此值設(shè)置為一個(gè)較大值犁河,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制鳖枕,這樣可以增加對(duì)象再年輕代的存活時(shí)間,增加在年輕代即被回收的概論桨螺。

新生代宾符、老生代、永久代的參數(shù)灭翔,如果不進(jìn)行指定魏烫,虛擬機(jī)會(huì)自動(dòng)選擇合適的值,同時(shí)也會(huì)基于系統(tǒng)的開銷自動(dòng)調(diào)整。

可調(diào)優(yōu)參數(shù):

  • -Xms:初始化堆內(nèi)存大小哄褒,默認(rèn)為物理內(nèi)存的1/64(小于1GB)稀蟋。
  • -Xmx:堆內(nèi)存最大值。默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時(shí)呐赡,JVM會(huì)減少堆直到-Xms的最小限制糊治。
  • -Xmn:新生代大小,包括Eden區(qū)與2個(gè)Survivor區(qū)罚舱。
  • -XX:SurvivorRatio=1:Eden區(qū)與一個(gè)Survivor區(qū)比值為1:1井辜。
  • -XX:MaxDirectMemorySize=1G:直接內(nèi)存。報(bào)java.lang.OutOfMemoryError: Direct buffer memory異彻苊疲可以上調(diào)這個(gè)值粥脚。
  • -XX:+DisableExplicitGC:禁止運(yùn)行期顯式地調(diào)用System.gc()來觸發(fā)fulll GC。
  • 注意: Java RMI的定時(shí)GC觸發(fā)機(jī)制可通過配置-Dsun.rmi.dgc.server.gcInterval=86400來控制觸發(fā)的時(shí)間包个。
  • -XX:CMSInitiatingOccupancyFraction=60:老年代內(nèi)存回收閾值刷允,默認(rèn)值為68。
  • -XX:ConcGCThreads=4:CMS垃圾回收器并行線程線碧囊,推薦值為CPU核心數(shù)树灶。
  • -XX:ParallelGCThreads=8:新生代并行收集器的線程數(shù)。
  • -XX:MaxTenuringThreshold=10:設(shè)置垃圾最大年齡糯而。如果設(shè)置為0的話天通,則年輕代對(duì)象不經(jīng)過Survivor區(qū),直接進(jìn)入年老代熄驼。對(duì)于年老代比較多的應(yīng)用像寒,可以提高效率。如果將此值設(shè)置為一個(gè)較大值瓜贾,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制诺祸,這樣可以增加對(duì)象再年輕代的存活時(shí)間,增加在年輕代即被回收的概論祭芦。
  • -XX:CMSFullGCsBeforeCompaction=4:指定進(jìn)行多少次fullGC之后筷笨,進(jìn)行tenured區(qū) 內(nèi)存空間壓縮。
  • -XX:CMSMaxAbortablePrecleanTime=500:當(dāng)abortable-preclean預(yù)清理階段執(zhí)行達(dá)到這個(gè)時(shí)間時(shí)就會(huì)結(jié)束龟劲。
  • 在設(shè)置的時(shí)候胃夏,如果關(guān)注性能開銷的話,應(yīng)盡量把永久代的初始值與最大值設(shè)置為同一值咸灿,因?yàn)橛谰么拇笮≌{(diào)整需要進(jìn)行FullGC才能實(shí)現(xiàn)构订。

內(nèi)存優(yōu)化示例

當(dāng)JVM運(yùn)行穩(wěn)定之后侮叮,觸發(fā)了FullGC我們一般會(huì)拿到如下信息:

以上gc日志中避矢,在發(fā)生fullGC之時(shí),整個(gè)應(yīng)用的堆占用以及GC時(shí)間。為了更加精確需多次收集审胸,計(jì)算平均值亥宿。或者是采用耗時(shí)最長的一次FullGC來進(jìn)行估算砂沛。上圖中烫扼,老年代空間占用在93168kb(約93MB),以此定為老年代空間的活躍數(shù)據(jù)碍庵。則其他堆空間的分配映企,基于以下規(guī)則來進(jìn)行。

  • java heap:參數(shù)-Xms和-Xmx静浴,建議擴(kuò)大至3-4倍FullGC后的老年代空間占用堰氓。
  • 永久代:-XX:PermSize和-XX:MaxPermSize,建議擴(kuò)大至1.2-1.5倍FullGc后的永久帶空間占用苹享。
  • 新生代:-Xmn双絮,建議擴(kuò)大至1-1.5倍FullGC之后的老年代空間占用。
  • 老年代:2-3倍FullGC后的老年代空間占用得问。

基于以上規(guī)則囤攀,則對(duì)參數(shù)定義如下:

java -Xms373m -Xmx373m -Xmn140m -XX:PermSize=5m -XX:MaxPermSize=5m

延遲優(yōu)化示例

對(duì)延遲性優(yōu)化,首先需要了解延遲性需求及可調(diào)優(yōu)的指標(biāo)有哪些宫纬。

  • 應(yīng)用程序可接受的平均停滯時(shí)間: 此時(shí)間與測(cè)量的Minor
  • GC持續(xù)時(shí)間進(jìn)行比較焚挠。可接受的Minor GC頻率:Minor
  • GC的頻率與可容忍的值進(jìn)行比較漓骚。
  • 可接受的最大停頓時(shí)間:最大停頓時(shí)間與最差情況下FullGC的持續(xù)時(shí)間進(jìn)行比較宣蔚。
  • 可接受的最大停頓發(fā)生的頻率:基本就是FullGC的頻率。

其中认境,平均停滯時(shí)間和最大停頓時(shí)間胚委,對(duì)用戶體驗(yàn)最為重要。對(duì)于上面的指標(biāo)叉信,相關(guān)數(shù)據(jù)采集包括:MinorGC的持續(xù)時(shí)間亩冬、統(tǒng)計(jì)MinorGC的次數(shù)、FullGC的最差持續(xù)時(shí)間硼身、最差情況下硅急,F(xiàn)ullGC的頻率稻励。

如上圖泻仙,Minor GC的平均持續(xù)時(shí)間0.069秒,MinorGC的頻率為0.389秒一次关霸。

新生代空間越大丑罪,Minor GC的GC時(shí)間越長荚板,頻率越低凤壁。如果想減少其持續(xù)時(shí)長,就需要減少其空間大小跪另。如果想減小其頻率拧抖,就需要加大其空間大小。

這里以減少了新生代空間10%的大小免绿,來減小延遲時(shí)間唧席。在此過程中,應(yīng)該保持老年代和持代的大小不變化嘲驾。調(diào)優(yōu)后的參數(shù)如下變化:

java -Xms359m -Xmx359m -Xmn126m -XX:PermSize=5m -XX:MaxPermSize=5m

吞吐量調(diào)優(yōu)

吞吐量調(diào)優(yōu)主要是基于應(yīng)用程序的吞吐量要求而來的淌哟,應(yīng)用程序應(yīng)該有一個(gè)綜合的吞吐指標(biāo),這個(gè)指標(biāo)基于整個(gè)應(yīng)用的需求和測(cè)試而衍生出來的辽故。

評(píng)估當(dāng)前吞吐量和目標(biāo)差距是否巨大绞绒,如果在20%左右,可以修改參數(shù)榕暇,加大內(nèi)存蓬衡,再次從頭調(diào)試,如果巨大就需要從整個(gè)應(yīng)用層面來考慮彤枢,設(shè)計(jì)以及目標(biāo)是否一致了狰晚,重新評(píng)估吞吐目標(biāo)。

對(duì)于垃圾收集器來說缴啡,提升吞吐量的性能調(diào)優(yōu)的目標(biāo)就是盡可能避免或者很少發(fā)生FullGC或者Stop-The-World壓縮式垃圾收集(CMS)壁晒,因?yàn)檫@兩種方式都會(huì)造成應(yīng)用程序吞吐降低。盡量在MinorGC 階段回收更多的對(duì)象业栅,避免對(duì)象提升過快到老年代秒咐。

調(diào)優(yōu)工具

借助GCViewer日志分析工具,可以非常直觀地分析出待調(diào)優(yōu)點(diǎn)碘裕⌒。可從以下幾方面來分析:

Memory,分析Totalheap、Tenuredheap帮孔、Youngheap內(nèi)存占用率及其他指標(biāo)雷滋,理論上內(nèi)存占用率越小越好;

Pause文兢,分析Gc pause晤斩、Fullgc pause、Total pause三個(gè)大項(xiàng)中各指標(biāo)姆坚,理論上GC次數(shù)越少越好澳泵,GC時(shí)長越小越好;

參考文獻(xiàn)

https://juejin.im/post/5dc8d0ea518825592c566a5d

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兼呵,一起剝皮案震驚了整個(gè)濱河市兔辅,隨后出現(xiàn)的幾起案子腊敲,更是在濱河造成了極大的恐慌,老刑警劉巖幢妄,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兔仰,死亡現(xiàn)場(chǎng)離奇詭異茫负,居然都是意外死亡蕉鸳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門忍法,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潮尝,“玉大人,你說我怎么就攤上這事饿序∶闶В” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵原探,是天一觀的道長乱凿。 經(jīng)常有香客問我,道長咽弦,這世上最難降的妖魔是什么徒蟆? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮型型,結(jié)果婚禮上段审,老公的妹妹穿的比我還像新娘。我一直安慰自己闹蒜,他們只是感情好寺枉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绷落,像睡著了一般姥闪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上砌烁,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天甘畅,我揣著相機(jī)與錄音,去河邊找鬼往弓。 笑死疏唾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的函似。 我是一名探鬼主播槐脏,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼撇寞!你這毒婦竟也來了顿天?” 一聲冷哼從身側(cè)響起堂氯,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎牌废,沒想到半個(gè)月后咽白,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸟缕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年晶框,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懂从。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡授段,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出番甩,到底是詐尸還是另有隱情侵贵,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布缘薛,位于F島的核電站窍育,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宴胧。R本人自食惡果不足惜漱抓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牺汤。 院中可真熱鬧辽旋,春花似錦、人聲如沸檐迟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽追迟。三九已至溶其,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敦间,已是汗流浹背瓶逃。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留廓块,地道東北人厢绝。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像带猴,于是被迫代替她去往敵國和親昔汉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容