自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

jvm系列(六):Java服務(wù)GC參數(shù)調(diào)優(yōu)案例

開(kāi)發(fā) 開(kāi)發(fā)工具 后端
總結(jié)來(lái)說(shuō),由于服務(wù)中大量使用了Cache,所以堆大小開(kāi)到了22G。GC算法使用CMS(UseConcMarkSweepGC),開(kāi)啟了降低標(biāo)記停頓(CMSParallelRemarkEnabled),設(shè)置年輕代為并行收集(UseParNewGC),年輕代和老年代的比例為1:2 (NewRatio=2).

[[206256]]

本文介紹了一次生產(chǎn)環(huán)境的JVM GC相關(guān)參數(shù)的調(diào)優(yōu)過(guò)程,通過(guò)參數(shù)的調(diào)整避免了GC卡頓對(duì)JAVA服務(wù)成功率的影響。

這段時(shí)間在整理jvm系列的文章,無(wú)意中發(fā)現(xiàn)本文,作者思路清晰通過(guò)步步分析最終解決問(wèn)題。我個(gè)人特別喜歡這種實(shí)戰(zhàn)類的內(nèi)容,經(jīng)原作者的授權(quán)同意,將文章分享于此。備注部分為本人添加,主要起到說(shuō)明的作用。

原文出處:https://segmentfault.com/a/1190000005174819

背景以及遇到的問(wèn)題

我們的Java HTTP服務(wù)屬于OLTP類型,對(duì)成功率和響應(yīng)時(shí)間的要求比較高,在生產(chǎn)環(huán)境中出現(xiàn)偶現(xiàn)的成功率突然下降然后又自動(dòng)恢復(fù)的情況,如圖所示:

JVM和GC相關(guān)的參數(shù)如下:

  1. -Xmx22528m  
  2. -Xms22528m  
  3. -XX:NewRatio=2  
  4. -XX:+UseConcMarkSweepGC  
  5. -XX:+UseParNewGC  
  6. -XX:+CMSParallelRemarkEnabled 

總結(jié)來(lái)說(shuō),由于服務(wù)中大量使用了Cache,所以堆大小開(kāi)到了22G。GC算法使用CMS(UseConcMarkSweepGC),開(kāi)啟了降低標(biāo)記停頓(CMSParallelRemarkEnabled),設(shè)置年輕代為并行收集(UseParNewGC),年輕代和老年代的比例為1:2 (NewRatio=2).

JVM GC日志相關(guān)的參數(shù)如下:

  1. -Xloggc:/data/gc.log  
  2. -XX:GCLogFileSize=10M  
  3. -XX:NumberOfGCLogFiles=10  
  4. -XX:+UseGCLogFileRotation  
  5. -XX:+PrintGCDateStamps  
  6. -XX:+PrintGCTimeStamps  
  7. -XX:+PrintGCDetails  
  8. -XX:+DisableExplicitGC  
  9. -verbose:gc 

問(wèn)題解決過(guò)程

排除應(yīng)用程序的內(nèi)存使用問(wèn)題

首先使用jmap查看內(nèi)存使用情況:

  1. jmap -histo:live PID 

這個(gè)命令把程序中當(dāng)前的對(duì)象按照個(gè)數(shù)和占用的空間排序以后打印出來(lái)。這里沒(méi)有發(fā)現(xiàn)使用異常的對(duì)象。

排除Cache內(nèi)容過(guò)多的問(wèn)題

如果Cache內(nèi)容過(guò)多也會(huì)導(dǎo)致JVM老年代容易被用滿導(dǎo)致頻繁GC,因此調(diào)出GC日志進(jìn)行查看,發(fā)現(xiàn)每次GC以后內(nèi)存使用一般是從20G降低到5G左右,因此常駐內(nèi)存的Cache不是導(dǎo)致GC長(zhǎng)時(shí)間卡頓的根本原因。對(duì)于GC LOG的查看有多種方式,使用VisualVM比較直觀,需要使用VisualGC:

從圖中我們可以看到伊甸園和老年代的空間分配,由于整體內(nèi)存是20G,設(shè)置 -XX:NewRatio=2 因此老年代是14G,伊甸園+S0+S1=7G

調(diào)整GC時(shí)間點(diǎn)(成功率抖動(dòng)問(wèn)題加重)

如果GC需要處理的內(nèi)存量比較大,執(zhí)行的時(shí)間也就比較長(zhǎng),STW (Stop the World)時(shí)間也就更長(zhǎng)。按照這個(gè)思路調(diào)整CMS啟動(dòng)的時(shí)間點(diǎn),希望提早GC,也就是讓GC變得更加頻繁但是期望每次執(zhí)行的時(shí)間較少。添加了下面這兩個(gè)參數(shù):

  1. -XX:+UseCMSInitiatingOccupancyOnly  
  2. -XX:CMSInitiatingOccupancyFraction=50 

意思是說(shuō)在Old區(qū)使用了50%的時(shí)候觸發(fā)GC。實(shí)驗(yàn)后發(fā)現(xiàn)GC的頻率有所增加,但是每次GC造成的陳功率降低現(xiàn)象并沒(méi)有減弱,因此棄用這兩個(gè)參數(shù)。

調(diào)整對(duì)象在年輕代內(nèi)存中駐留的時(shí)間(效果不明顯)

如果能夠降低老年代GC的頻率也可以達(dá)到降低GC影響的目的,因此嘗試讓對(duì)象在年輕代內(nèi)存中進(jìn)行更長(zhǎng)時(shí)間的駐留,提升這些對(duì)象在年輕代GC時(shí)候被銷毀的概率。使用參數(shù) -XX:MaxTenuringThreshold=31調(diào)整以后收效不明顯。

備注:

1、MaxTenuringThreshold 在1.5.005之前***值可以設(shè)置為31 ,1.5.006以后***值可以設(shè)置為15,超過(guò)15會(huì)被認(rèn)為***大。

2、提升年輕代GC被銷毀的概率,只是調(diào)整這個(gè)參數(shù)效果不大,第二次age的值會(huì)重新計(jì)算。

CMS-Remark之前強(qiáng)制進(jìn)行年輕代的GC

首先補(bǔ)充一下CMS的相關(guān)知識(shí),在CMS整個(gè)過(guò)程中有兩個(gè)步驟是STW的,如圖紅色部分:

CMS并非沒(méi)有暫停,而是用兩次短暫停來(lái)替代串行標(biāo)記整理算法的長(zhǎng)暫停,它的收集周期是這樣:

1、初始標(biāo)記(CMS-initial-mark),從root對(duì)象開(kāi)始標(biāo)記存活的對(duì)象

2、并發(fā)標(biāo)記(CMS-concurrent-mark)

3、重新標(biāo)記(CMS-remark),暫停所有應(yīng)用程序線程,重新標(biāo)記并發(fā)標(biāo)記階段遺漏的對(duì)象(在并發(fā)標(biāo)記階段結(jié)束后對(duì)象狀態(tài)的更新導(dǎo)致)

4、并發(fā)清除(CMS-concurrent-sweep)

5、并發(fā)重設(shè)狀態(tài)等待下次CMS的觸發(fā)(CMS-concurrent-reset)。

通過(guò)GC日志和成功率下降的時(shí)間點(diǎn)進(jìn)行比對(duì)發(fā)現(xiàn)并不是每一次老年代GC都會(huì)導(dǎo)致成功率的下降,但是從中發(fā)現(xiàn)了一個(gè)規(guī)律:

前兩次GC CMS-Remark過(guò)程在4s左右造成了成功率的下降,但是第三次GC并沒(méi)有對(duì)成功率造成明顯的影響,CMS-Remark只有0.18s。Java HTTP 服務(wù)是通過(guò)Nginx進(jìn)行反向代理的,nginx設(shè)置的超時(shí)時(shí)間是3s,所以如果GC卡頓在3s以內(nèi)就不會(huì)對(duì)成功率造成太大的影響。

從GC日志中又發(fā)現(xiàn)一個(gè)信息:

在文檔和相關(guān)資料中沒(méi)有找到藍(lán)色部分的含義,猜測(cè)是remark處理的內(nèi)存量,處理的越多就越慢。添加下面兩個(gè)參數(shù)強(qiáng)制在remark階段和FULL GC階段之前先在進(jìn)行一次年輕代的GC,這樣需要進(jìn)行處理的內(nèi)存量就

  1. XX:+ScavengeBeforeFullGC   
  2. -XX:+CMSScavengeBeforeRemark 

備注:

1、藍(lán)色部分的含義:remark標(biāo)記需要清理對(duì)象的容量。

2、FULL GC階段之前先在進(jìn)行一次年輕代的GC的意義是:Yong區(qū)對(duì)象引用了Old區(qū)的對(duì)象,如果在Old區(qū)進(jìn)行清理之前不進(jìn)行Yong區(qū)清理,就會(huì)導(dǎo)致Old區(qū)被Yong區(qū)引用的對(duì)象無(wú)法釋放。

調(diào)優(yōu)以后效果很明顯,下面是兩臺(tái)配置完全相同的服務(wù)器在同一時(shí)間段的成功率和響應(yīng)時(shí)間監(jiān)控圖,***個(gè)沒(méi)有添加強(qiáng)制年輕代GC的參數(shù)。

結(jié)論

1、在CMS-remark階段需要對(duì)堆中所有的內(nèi)存對(duì)象進(jìn)行處理,如果在這個(gè)階段之前強(qiáng)制執(zhí)行一次年輕代的GC會(huì)大量減少remark需要處理的內(nèi)存數(shù)量,進(jìn)而降低JVM卡頓對(duì)成功率的影響。

2、對(duì)于Java HTTP服務(wù),JVM的卡頓時(shí)間應(yīng)該小于HTTP客戶端的調(diào)用超時(shí)時(shí)間,否則JVM卡頓會(huì)對(duì)成功率造成影響。

【本文為51CTO專欄作者“純潔的微笑”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)微信公眾號(hào)聯(lián)系作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專欄
相關(guān)推薦

2021-03-17 11:35:11

JVM代碼Java

2017-10-17 14:02:30

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

2017-09-22 15:15:23

jvm調(diào)優(yōu)命令

2010-09-25 13:05:07

JVM參數(shù)

2010-03-04 10:56:52

JVM參數(shù)

2023-11-10 11:23:20

JVM內(nèi)存

2023-12-12 08:00:39

2012-01-10 14:35:08

JavaJVM

2010-09-17 17:02:24

JVM參數(shù)

2017-07-21 08:55:13

TomcatJVM容器

2017-09-26 16:32:03

JavaGC分析

2023-11-11 19:07:23

JVMJava

2023-01-16 08:19:25

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

2021-09-06 11:02:17

JVM架構(gòu)調(diào)優(yōu)

2023-10-13 12:28:38

2012-01-10 15:13:56

JavaJVM

2010-09-26 13:39:46

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

2010-09-26 09:08:17

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

2017-11-08 15:23:57

Java GC優(yōu)化jvm

2021-06-03 08:32:18

JVM調(diào)優(yōu)虛擬機(jī)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)