2019-11-15 JVM參數(shù)調(diào)優(yōu)推薦

關(guān)鍵業(yè)務(wù)系統(tǒng)的JVM參數(shù)推薦(2018仲夏版)

Posted on 2018-07-20 by calvin

年更貼讹挎,因?yàn)閮赡昀镉龅降氖虑榛酉拢恍┫敕ㄗ兞税挛瘛R惭a(bǔ)充了不少VJTools的內(nèi)容卢佣,比如為伸手黨們準(zhǔn)備的jvm-options.sh欺缘。

在關(guān)鍵的業(yè)務(wù)系統(tǒng)里栋豫,除了繼續(xù)追求技術(shù)人員最愛的高吞吐與低延時(shí)之外,系統(tǒng)的穩(wěn)定性與排查問題的便捷性也很重要谚殊。這是本文的一個(gè)原則丧鸯,后面也會(huì)一次又一次的強(qiáng)調(diào)。

前言1嫩絮,資料

1. 學(xué)習(xí)開源項(xiàng)目的啟動(dòng)腳本是個(gè)不錯(cuò)的主意丛肢,比如ElasticSearch家的Cassandra家的絮记, 附送一篇解釋它的文章摔踱。

2. VJTools的 jvm-options.sh,伸手黨們最愛怨愤,根據(jù)自己需要稍微定制一下就行派敷。

  1. JVM調(diào)優(yōu)的"標(biāo)準(zhǔn)參數(shù)"的各種陷阱 ,R大的文章,在JDK6時(shí)寫的篮愉,年年期待更新腐芍。

前言2, -XX:+PrintFlagsFinal打印參數(shù)值

當(dāng)你在網(wǎng)上興沖沖找到一個(gè)可優(yōu)化的參數(shù)時(shí)试躏,先用-XX: +PrintFlagsFinal看看猪勇,它可能已經(jīng)默認(rèn)打開了,再找到一個(gè)颠蕴,還是默認(rèn)打開了...

JDK7與JDK8泣刹,甚至JDK7中的不同小版本,有些參數(shù)值都不一樣犀被,所以不要輕信網(wǎng)上任何文章椅您,一切以生產(chǎn)環(huán)境同版本的JDK打出來的為準(zhǔn)。

經(jīng)常以類似下面的語句去查看參數(shù)寡键,偷懶不起應(yīng)用掀泳,用-version代替。有些參數(shù)設(shè)置后會(huì)影響其他參數(shù)西轩,所以也要帶上员舵。

java -Xmx1024m -Xms1024m -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -version| grep ParallelGCThreads

對(duì)于不同版本里的默認(rèn)值,建議是順勢(shì)而為藕畔,JDK在那個(gè)版本默認(rèn)打開不打開總有它的理由马僻。安全第一,沒有很好的因由劫流,不要隨便因?yàn)榫W(wǎng)上某篇文章的推薦(包括你現(xiàn)在在讀的這篇)就去設(shè)置巫玻。

1. 性能篇

1.1 建議的性能參數(shù)

1. 取消偏向鎖 -XX:-UseBiasedLocking

JDK1.6開始默認(rèn)打開的偏向鎖,會(huì)嘗試把鎖賦給第一個(gè)訪問它的線程祠汇,取消同步塊上的synchronized原語。如果始終只有一條線程在訪問它熄诡,就成功略過同步操作以獲得性能提升可很。

但一旦有第二條線程訪問這把鎖,JVM就要撤銷偏向鎖恢復(fù)到未鎖定線程的狀態(tài)凰浮,如果打開安全點(diǎn)日志我抠,可以看到不少RevokeBiasd的紀(jì)錄,像GC一樣Stop The World的干活袜茧,雖然只是很短的停頓菜拓,但對(duì)于多線程并發(fā)的應(yīng)用,取消掉它反而有性能的提升笛厦,所以Cassandra就取消了它纳鼎。

2. 加大Integer Cache -XX:AutoBoxCacheMax=20000

Integer i=3;這語句有著 int自動(dòng)裝箱成Integer的過程,JDK默認(rèn)只緩存 -128 ~ +127的Integer 和 Long,超出范圍的數(shù)字就要即時(shí)構(gòu)建新的Integer對(duì)象贱鄙。設(shè)為20000后劝贸,我們應(yīng)用的QPS有足足4%的影響。為什么是2萬呢逗宁,因?yàn)?strong>-XX:+AggressiveOpts里也是這個(gè)值映九。詳見Java Integer(-128~127)值的==和equals比較產(chǎn)生的思考

3. 啟動(dòng)時(shí)訪問并置零內(nèi)存頁面 -XX:+AlwaysPreTouch

啟動(dòng)時(shí)就把參數(shù)里說好了的內(nèi)存全部舔一遍瞎颗,可能令得啟動(dòng)時(shí)慢上一點(diǎn)件甥,但后面訪問時(shí)會(huì)更流暢,比如頁面會(huì)連續(xù)分配哼拔,比如不會(huì)在晉升新生代到老生代時(shí)才去訪問頁面使得GC停頓時(shí)間加長嚼蚀。ElasticSearch和Cassandra都打開了它。

4. SecureRandom生成加速 -Djava.security.egd=file:/dev/./urandom

此江湖偏方原因?yàn)門omcat的SecureRandom顯式使用SHA1PRNG算法時(shí)管挟,初始因子默認(rèn)從/dev/random讀取會(huì)存在堵塞轿曙。額外效果是SecureRandom的默認(rèn)算法也變成合適的SHA1了。詳見 SecureRandom的江湖偏方與真實(shí)效果

1.2 可選的性能參數(shù)

1. -XX:+PerfDisableSharedMem

Cassandra家的一個(gè)參數(shù)僻孝,一直沒留意导帝,直到發(fā)生高IO時(shí)的JVM停頓。原來JVM經(jīng)常會(huì)默默的在/tmp/hperf 目錄寫上一點(diǎn)statistics數(shù)據(jù)穿铆,如果剛好遇到PageCache刷盤您单,把文件阻塞了,就不能結(jié)束這個(gè)Stop the World的安全點(diǎn)了荞雏。
禁止JVM寫statistics數(shù)據(jù)的代價(jià)虐秦,是jps和jstat 用不了,只能用JMX凤优,而JMX取新老生代的使用百分比還真沒jstat方便悦陋,VJTools VJTools里的vjmxcli彌補(bǔ)了這一點(diǎn)。詳見The Four Month Bug: JVM statistics cause garbage collection pauses

2. -XX:-UseCounterDecay

禁止JIT調(diào)用計(jì)數(shù)器衰減筑辨。默認(rèn)情況下俺驶,每次GC時(shí)會(huì)對(duì)調(diào)用計(jì)數(shù)器進(jìn)行砍半的操作,導(dǎo)致有些方法一直溫?zé)峁髟肋h(yuǎn)都達(dá)不到觸發(fā)C2編譯的1萬次的閥值暮现。

3. -XX:-TieredCompilation

多層編譯是JDK8后默認(rèn)打開的比較驕傲的功能,先以C1靜態(tài)編譯楚昭,采樣足夠后C2編譯栖袋。

但我們實(shí)測(cè),性能最終略降2%抚太,可能是因?yàn)橛行┓椒–1編譯后C2不再編譯了塘幅。應(yīng)用啟動(dòng)時(shí)的偶發(fā)服務(wù)超時(shí)也多了昔案,可能是忙于編譯。所以我們將它禁止了晌块,但記得打開前面的-XX:-UseCounterDecay爱沟,避免有些溫?zé)岬姆椒ㄓ肋h(yuǎn)都要解釋執(zhí)行。

1.3 不建議的性能參數(shù)

1. -XX:+AggressiveOpts

一些還沒默認(rèn)打開的優(yōu)化參數(shù)集合, -XX:AutoBoxCacheMax是其中的一項(xiàng)匆背。但如前所述呼伸,關(guān)鍵系統(tǒng)里不建議打開。雖然通過-XX:+AggressiveOpts 與 -XX:-AggressiveOpts 的對(duì)比钝尸,目前才改變了三個(gè)參數(shù)括享,但為免以后某個(gè)版本的JDK里默默改變更多激進(jìn)的配置,還是不要打開了珍促。

2. JIT Compile相關(guān)的參數(shù)铃辖,函數(shù)調(diào)用多少次之后開始編譯的閥值,內(nèi)聯(lián)函數(shù)大小的閥值等等猪叙,不要亂改娇斩。

  1. -server,在64位多核的linux中穴翩,你想設(shè)成-client都不行的犬第,所以寫了也是白寫。

2. 內(nèi)存與GC篇

2.1 GC策略

為了穩(wěn)健芒帕,還是8G以下的堆還是CMS好了歉嗓,G1現(xiàn)在雖然是默認(rèn)了,但其實(shí)在小堆里的表現(xiàn)也沒有比CMS好背蟆,還是JDK11的ZGC引人期待鉴分。

1.CMS基本寫法

-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly

因?yàn)槲覀兊谋O(jiān)控系統(tǒng)會(huì)通過JMX監(jiān)控內(nèi)存達(dá)到90%的狀況,所以設(shè)置讓它75%就開始跑了带膀,早點(diǎn)開始也能減少Full GC等意外情況(概念重申志珍,這種主動(dòng)的CMS GC,和JVM的老生代本砰、永久代碴裙、堆外內(nèi)存完全不能分配內(nèi)存了而強(qiáng)制Full GC是不同的概念)。
為了讓這個(gè)設(shè)置生效点额,還要設(shè)置-XX:+UseCMSInitiatingOccupancyOnly,否則75%只被用來做開始的參考值莺琳,后面還是JVM自己算还棱。

2. -XX:MaxTenuringThreshold=2

這是改動(dòng)效果最明顯的一個(gè)參數(shù)了。對(duì)象在Survivor區(qū)最多熬過多少次Young GC后晉升到年老代惭等,JDK8里CMS 默認(rèn)是6珍手,其他如G1是15。

Young GC是最大的應(yīng)用停頓來源,而新生代里GC后存活對(duì)象的多少又直接影響停頓的時(shí)間琳要,所以如果清楚Young GC的執(zhí)行頻率和應(yīng)用里大部分臨時(shí)對(duì)象的最長生命周期寡具,可以把它設(shè)的更短一點(diǎn),讓其實(shí)不是臨時(shí)對(duì)象的新生代對(duì)象趕緊晉升到年老代稚补,別呆著童叠。

用-XX:+PrintTenuringDistribution觀察下,如果后面幾代的大小總是差不多课幕,證明過了某個(gè)年齡后的對(duì)象總能晉升到老生代厦坛,就可以把晉升閾值設(shè)小,比如JMeter里2就足夠了乍惊。

3. -XX:+ExplicitGCInvokesConcurrent 但不要-XX:+DisableExplicitGC

?full gc時(shí)杜秸,使用CMS算法,不是全程停頓润绎,必選撬碟。

但像R大說的,System GC是保護(hù)機(jī)制(如堆外內(nèi)存滿時(shí)清理它的堆內(nèi)引用對(duì)象)莉撇,禁了system.gc() 未必是好事呢蛤,只要沒用什么特別爛的類庫,真有人調(diào)了總有調(diào)的原因稼钩,所以不應(yīng)該加這個(gè)爛大街的參數(shù)顾稀。

4. ParallelRefProcEnabled 和 CMSParallelInitialMarkEnabled

并行的處理Reference對(duì)象,如WeakReference坝撑,默認(rèn)為false静秆,除非在GC log里出現(xiàn)Reference處理時(shí)間較長的日志,否則效果不會(huì)很明顯巡李,但我們總是要JVM盡量的并行抚笔,所以設(shè)了也就設(shè)了。同理還有-XX:+CMSParallelInitialMarkEnabled侨拦,JDK8已默認(rèn)開啟殊橙,但小版本比較低的JDK7甚至不支持浩考。

5. ParGCCardsPerStrideChunk

Linkined的黑科技啡捶, 上一個(gè)版本的文章不建議打開商玫,后來發(fā)現(xiàn)有些場(chǎng)景的確能減少YGC時(shí)間黑竞,詳見難道他們說的都是真的拍鲤,簡單說就是影響YGC時(shí)掃描老生代的時(shí)間富腊,默認(rèn)值256太小了狮惜,但32K也未必對(duì)圾旨,需要自己試驗(yàn)与涡。

-XX:+UnlockDiagnosticVMOptions -XX: ParGCCardsPerStrideChunk=1024

2.2 可選的GC參數(shù)

1. 并發(fā)收集線程數(shù)

ParallelGCThreads=8+( Processor - 8 ) ( 5/8 )惹谐;
ConcGCThreads = (ParallelGCThreads + 3)/4

比如雙CPU持偏,六核,超線程就是24個(gè)處理器氨肌,小于8個(gè)處理器時(shí)ParallelGCThreads按處理器數(shù)量鸿秆,大于時(shí)按上述公式Y(jié)GC線程數(shù)=18, CMS GC線程數(shù)=5怎囚。

CMS GC線程數(shù)的公式太怪卿叽,也有人提議簡單改為YGC線程數(shù)的1/2。

一些不在乎停頓時(shí)間的后臺(tái)輔助程序桩了,比如日志收集的logstash附帽,建議把它減少到2,避免在GC時(shí)突然占用太多CPU核井誉,影響主應(yīng)用蕉扮。

而另一些并不獨(dú)占服務(wù)器的應(yīng)用,比如旁邊跑著一堆sidecar的颗圣,也建議減少YGC線程數(shù)喳钟。

一個(gè)真實(shí)的案例,24核的服務(wù)器在岂,默認(rèn)18條YGC線程奔则,但因?yàn)榕赃呌袀€(gè)繁忙的Service Mesh Proxy在跑著,這18條線程并不能100%的搶到CPU蔽午,出現(xiàn)了不合理的慢GC易茬。把線程數(shù)降低到12條之后,YGC反而快了很多及老。 所以那些貪心的把YGC線程數(shù)=CPU 核數(shù)的抽莱,通常弄巧成拙。

2. -XX:-CMSClassUnloadingEnabled

在CMS中清理永久代中的過期的Class而不等到Full GC骄恶,JDK7默認(rèn)關(guān)閉而JDK8打開食铐。看自己情況僧鲁,比如有沒有運(yùn)行動(dòng)態(tài)語言腳本如Groovy產(chǎn)生大量的臨時(shí)類虐呻。它有時(shí)會(huì)大大增加CMS的暫停時(shí)間。所以如果新類加載并不頻繁寞秃,這個(gè)參數(shù)還是顯式關(guān)閉的好斟叼。

3. -XX:+CMSScavengeBeforeRemark

默認(rèn)為關(guān)閉,在CMS remark前春寿,先執(zhí)行一次minor GC將新生代清掉犁柜,這樣從老生代的對(duì)象引用到的新生代對(duì)象的個(gè)數(shù)就少了,停止全世界的CMS remark階段就短一些堂淡。如果打開了馋缅,會(huì)讓一次YGC緊接著一次CMS GC,使得停頓的總時(shí)間加長了绢淀。

又一個(gè)真實(shí)案例萤悴,CMS GC的時(shí)間和當(dāng)時(shí)新生代的大小成比例,新生代很小時(shí)很快完成皆的,新生代80%時(shí)CMS GC停頓時(shí)間超過一秒覆履,這時(shí)候就還是打開了劃算。

2.3 不建議的GC參數(shù)

1. -XX:+UseParNewGC

用了CMS费薄,新生代收集默認(rèn)就是硝全,不用自己設(shè)。

2. -XX:CMSFullGCsBeforeCompaction
默認(rèn)為0楞抡,即每次full gc都對(duì)老生代進(jìn)行碎片整理壓縮伟众。Full GC 不同于 老生代75%時(shí)觸發(fā)的CMS GC,只在老生代達(dá)到100%召廷,老生代碎片過大無法分配空間給新晉升的大對(duì)象凳厢,堆外內(nèi)存滿,這些特殊情況里發(fā)生竞慢,所以設(shè)為每次都進(jìn)行碎片整理是合適的先紫,詳見此貼里R大的解釋

3.-XX:+GCLockerInvokesConcurrent

我們犯過的錯(cuò)筹煮,不是所有Concurrent字樣的參數(shù)都是好參數(shù)遮精,加上之后,原本遇上JNI GCLocker只需要補(bǔ)償YGC就夠的败潦,變成要執(zhí)行YGC + CMS GC了本冲。

2.4 內(nèi)存大小的設(shè)置

其實(shí)JVM除了顯式設(shè)置的-Xmx堆內(nèi)存,還有一堆其他占內(nèi)存的地方(堆外內(nèi)存变屁,線程棧眼俊,永久代,二進(jìn)制代碼cache)粟关,在容量規(guī)劃的時(shí)候要留意疮胖。

關(guān)鍵業(yè)務(wù)系統(tǒng)的服務(wù)器上內(nèi)存一般都是夠的,所以盡管設(shè)得寬松點(diǎn)闷板。

1. -Xmx, -Xms,
堆內(nèi)存大小澎灸,2~4G均可。

2. -Xmn or -XX:NewSize or -XX:NewRatio

JDK默認(rèn)新生代占堆大小的1/3遮晚, 個(gè)人喜歡把對(duì)半分性昭, 因?yàn)樵龃笮律軠p少GC的頻率,如果老生代里沒多少長期對(duì)象的話县遣,占2/3通常太多了糜颠⌒谧澹可以用-Xmn 直接賦值(等于-XX:NewSize and -XX:MaxNewSize同值的縮寫),或把NewRatio設(shè)為1來對(duì)半分其兴。

3. -XX: PermSize=128m -XX:MaxPermSize=512m (JDK7)
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m(JDK8)

現(xiàn)在的應(yīng)用有Hibernate/Spring這些鬧騰的家伙AOP之后類都比較多顶瞒,可以一開始就把初始值從64M設(shè)到128M(否則第一次自動(dòng)擴(kuò)張會(huì)造成大約3秒的JVM停頓),并設(shè)一個(gè)更大的Max值以求保險(xiǎn)元旬。

JDK8的永生代幾乎可用完機(jī)器的所有內(nèi)存榴徐,同樣設(shè)一個(gè)128M的初始值,512M的最大值保護(hù)一下匀归。

2.5 其他內(nèi)存大小的設(shè)置

1. -Xss

在堆之外坑资,線程占用棧內(nèi)存,默認(rèn)每條線程為1M(以前是256K)穆端。存放方法調(diào)用出參入?yún)⒌臈8ぶ植孔兞浚瑯?biāo)量替換后掉局部變量等徙赢,有人喜歡把它設(shè)回256k字柠,節(jié)約內(nèi)存并開更多線程,有人則會(huì)在遇到錯(cuò)誤后把它再設(shè)大點(diǎn)狡赐,特別是有很深的JSON解析之類的遞歸調(diào)用時(shí)窑业。

2. -XX:SurvivorRatio

新生代中每個(gè)存活區(qū)的大小,默認(rèn)為8枕屉,即1/10的新生代 1/(SurvivorRatio+2)常柄,有人喜歡設(shè)小點(diǎn)省點(diǎn)給新生代如Cassandra,但要避免太小使得存活區(qū)放不下臨時(shí)對(duì)象而被迫晉升到老生代搀擂,還是從GC日志里看實(shí)際情況了西潘。

3. -XX:MaxDirectMemorySize

堆外內(nèi)存的最大值,默認(rèn)為Heap區(qū)總內(nèi)存減去一個(gè)Survivor區(qū)的大小哨颂,詳見Netty之堆外內(nèi)存掃盲篇喷市,如果肯定用不了這么多,也可以把它主動(dòng)設(shè)小威恼,來獲得一個(gè)比較清晰內(nèi)存占用預(yù)估值品姓,特別是在容器里。

4. -XX:ReservedCodeCacheSize

JIT編譯后二進(jìn)制代碼的存放區(qū)箫措,滿了之后就不再編譯腹备,對(duì)性能影響很大。初始值為2M斤蔓, 不開多層編譯時(shí)最大值為48M植酥,開了的話JDK7是96M,JDK8是240M∮淹裕可以在JMX里看看CodeCache的占用情況漂羊,也可以用VJTools里的vjtop來看,JDK7下默認(rèn)的48M可以設(shè)大點(diǎn)喊儡,不摳這么點(diǎn)拨与。

3. 監(jiān)控篇

JVM輸出的各種日志,如果未指定路徑艾猜,通常會(huì)生成到運(yùn)行應(yīng)用的相同目錄,為了避免有時(shí)候在不同的地方執(zhí)行啟動(dòng)腳本捻悯,一般將日志路徑集中設(shè)到一個(gè)固定的地方匆赃。

3.1 監(jiān)控建議配置

1. -XX:+PrintCommandLineFlags

運(yùn)維有時(shí)會(huì)對(duì)啟動(dòng)參數(shù)做一些臨時(shí)的更改,將每次啟動(dòng)的參數(shù)輸出到stdout今缚,將來有據(jù)可查算柳。
打印出來的是命令行里設(shè)置了的參數(shù)以及因?yàn)檫@些參數(shù)隱式影響的參數(shù),比如開了CMS后姓言,-XX:+UseParNewGC也被自動(dòng)打開瞬项。

2. -XX:-OmitStackTraceInFastThrow

為異常設(shè)置StackTrace是個(gè)昂貴的操作,所以當(dāng)應(yīng)用在相同地方拋出相同的異常N次(兩萬?)之后何荚,JVM會(huì)對(duì)某些特定異常如NPE囱淋,數(shù)組越界等進(jìn)行優(yōu)化,不再帶上異常棧餐塘。此時(shí)妥衣,你可能會(huì)看到日志里一條條Nul Point Exception,而之前輸出完整棧的日志早被滾動(dòng)到不知哪里去了戒傻,也就完全不知道這NPE發(fā)生在什么地方税手,欲哭無淚。 所以需纳,將它禁止吧芦倒,ElasticSearch也這樣干。

3.2 Crash文件

1. -XX:ErrorFile

JVM crash時(shí)不翩,hotspot 會(huì)生成一個(gè)error文件兵扬,提供JVM狀態(tài)信息的細(xì)節(jié)。如前所述慌盯,將其輸出到固定目錄周霉,避免到時(shí)會(huì)到處找這文件。文件名中的%p會(huì)被自動(dòng)替換為應(yīng)用的PID

-XX:ErrorFile=${MYLOGDIR}/hs_err_%p.log

2. coredump

當(dāng)然亚皂,更好的做法是生成coredump俱箱,從CoreDump能夠轉(zhuǎn)出Heap Dump 和 Thread Dump 還有crash的地方,非常實(shí)用灭必。

在啟動(dòng)腳本里加上 ulimit -c unlimited或其他的設(shè)置方式狞谱,如果有root權(quán)限乃摹,設(shè)一下輸出目錄更好

echo "/{MYLOGDIR}/coredump.%p" > /proc/sys/kernel/core_pattern

什么?你不知道coredump有什么用跟衅?看來你是沒遇過JVM Segment Fault的幸福人孵睬。

3. -XX:+HeapDumpOnOutOfMemoryError(可選)

在Out Of Memory,JVM快死掉的時(shí)候伶跷,輸出Heap Dump到指定文件掰读。不然開發(fā)很多時(shí)候還真不知道怎么重現(xiàn)錯(cuò)誤。

路徑只指向目錄叭莫,JVM會(huì)保持文件名的唯一性蹈集,叫java_pid${pid}.hprof。因?yàn)槿绻赶蛭募统酰募汛嬖诼K粒炊荒軐懭搿?/p>

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGDIR}/

但在容器環(huán)境下,輸出4G的HeapDump靖诗,在普通硬盤上會(huì)造成20秒以上的硬盤IO跑滿郭怪,也是個(gè)十足的惡鄰,影響了同一宿主機(jī)上所有其他的容器刊橘。

3.3 GC日志

JDK9完全不一樣了鄙才,這里還是寫JDK7/8的配置。

1.基本配置

-Xloggc:/dev/shm/gc-myapp.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails

有人擔(dān)心寫GC日志會(huì)影響性能伤为,但測(cè)試下來實(shí)在沒什么影響咒循,GC問題是Java里最常見的問題,沒日志怎么行绞愚。

后來又發(fā)現(xiàn)如果遇上高IO的情況叙甸,GC時(shí)操作系統(tǒng)正在flush pageCache 到磁盤,也可能導(dǎo)致GC log文件被鎖住位衩,從而讓GC結(jié)束不了裆蒸。所以把它指向了/dev/shm 這種內(nèi)存中文件系統(tǒng),避免這種停頓糖驴,詳見Eliminating Large JVM GC Pauses Caused by Background IO Traffic

用PrintGCDateStamps而不是PrintGCTimeStamps僚祷,打印可讀的日期而不是時(shí)間戳。

2. -XX:+PrintGCApplicationStoppedTime

這是個(gè)非常非常重要的參數(shù)贮缕,但它的名字沒起好辙谜,其實(shí)除了打印清晰的完整的GC停頓時(shí)間外,還可以打印其他的JVM停頓時(shí)間感昼,比如取消偏向鎖装哆,class 被agent redefine,code deoptimization等等,有助于發(fā)現(xiàn)一些原來沒想到的問題蜕琴。如果真的發(fā)現(xiàn)了一些不知是什么的停頓萍桌,需要打印安全點(diǎn)日志找原因(見后)。

3. -XX:+PrintGCCause

打印產(chǎn)生GC的原因凌简,比如AllocationFailure什么的上炎,在JDK8已默認(rèn)打開,JDK7要顯式打開一下雏搂。

4. -XX:+PrintPromotionFailure

打開了就知道是多大的新生代對(duì)象晉升到老生代失敗從而引發(fā)Full GC時(shí)的藕施。

5. GC日志滾動(dòng)與備份

GC日志默認(rèn)會(huì)在重啟后清空,有人擔(dān)心長期運(yùn)行的應(yīng)用會(huì)把文件弄得很大畔派,所以"-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M"的參數(shù)可以讓日志滾動(dòng)起來铅碍。但真正用起來重啟后的文件名太混亂太讓人頭痛,GC日志再大也達(dá)不到哪里去线椰,所以我們沒有加滾動(dòng),而且自行在啟動(dòng)腳本里對(duì)舊日志做備份尘盼。

3.4 安全點(diǎn)日志

如果GC日志里有非GC的JVM停頓時(shí)間憨愉,你得打出安全點(diǎn)日志來知道詳情,詳見 JVM的Stop The World卿捎,安全點(diǎn)配紫,黑暗的地底世界

-XX:+PrintSafepointStatistics -XX: PrintSafepointStatisticsCount=1 -XX:+UnlockDiagnosticVMOptions -XX:- DisplayVMOutput -XX:+LogVMOutput -XX:LogFile=/dev/shm/vm-myapp.log

3.5 JMX

-Dcom.sun.management.jmxremote.port=7001 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1

以上設(shè)置,只讓本地的Zabbix之類監(jiān)控軟件通過JMX監(jiān)控JVM午阵,不允許遠(yuǎn)程訪問躺孝。

如果應(yīng)用忘記了加上述參數(shù),又不想改參數(shù)重啟服務(wù)底桂,可以用VJTools的vjmxcli來救急植袍,它能通過PID直接連入目標(biāo)JVM打開JMX。

4. 小結(jié)

VJTools剛剛開源了籽懦,里頭東西不少于个,比如 jvm-options.sh,伸手黨們最愛暮顺,再啰嗦一次厅篓,麻煩大家給項(xiàng)目點(diǎn)個(gè)Star。

有什么寫得不對(duì)的地方捶码,明年再來更新啦羽氮。祝大家生產(chǎn)環(huán)境里的JVM都穩(wěn)健無比,永遠(yuǎn)沒bug惫恼。

《關(guān)鍵業(yè)務(wù)系統(tǒng)的JVM啟動(dòng)參數(shù)推薦》档押,轉(zhuǎn)載請(qǐng)保留鏈接。

有關(guān)的...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市掀淘,隨后出現(xiàn)的幾起案子旬蟋,更是在濱河造成了極大的恐慌,老刑警劉巖革娄,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倾贰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拦惋,警方通過查閱死者的電腦和手機(jī)匆浙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厕妖,“玉大人首尼,你說我怎么就攤上這事⊙越眨” “怎么了软能?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長举畸。 經(jīng)常有香客問我查排,道長,這世上最難降的妖魔是什么抄沮? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任跋核,我火速辦了婚禮,結(jié)果婚禮上叛买,老公的妹妹穿的比我還像新娘砂代。我一直安慰自己,他們只是感情好聪全,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布泊藕。 她就那樣靜靜地躺著,像睡著了一般难礼。 火紅的嫁衣襯著肌膚如雪娃圆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天蛾茉,我揣著相機(jī)與錄音讼呢,去河邊找鬼。 笑死谦炬,一個(gè)胖子當(dāng)著我的面吹牛悦屏,可吹牛的內(nèi)容都是我干的节沦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼础爬,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼甫贯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起看蚜,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤叫搁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后供炎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渴逻,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年音诫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惨奕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竭钝,死狀恐怖梨撞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情香罐,我是刑警寧澤聋袋,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站穴吹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嗜侮。R本人自食惡果不足惜港令,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锈颗。 院中可真熱鬧顷霹,春花似錦、人聲如沸击吱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽覆醇。三九已至朵纷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間永脓,已是汗流浹背袍辞。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留常摧,地道東北人搅吁。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓威创,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谎懦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肚豺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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

  • 轉(zhuǎn)載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,356評(píng)論 1 56
  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動(dòng)之前,它的class會(huì)被類裝載器裝入方法區(qū)(Permanent區(qū))界拦,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,650評(píng)論 0 7
  • 作者:一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-12】 更新日志 日期更新內(nèi)容備注 2017-11-12新建文章初版 ...
    beneke閱讀 2,195評(píng)論 0 7
  • Tomcat 的缺省配置是不能穩(wěn)定長期運(yùn)行的吸申,也就是不適合生產(chǎn)環(huán)境,它會(huì)死機(jī)寞奸,讓你不斷重新啟動(dòng)呛谜,甚至在午夜時(shí)分喚醒...
    憤怒的_菜鳥閱讀 2,111評(píng)論 0 24
  • 近來感慨最多的就是時(shí)間過得太快,貌似嗖的一聲就到十一月了枪萄。有時(shí)候在想如果一天有48小時(shí)就好了隐岛,可惜沒如果。正因?yàn)橐?..
    LimeiDeng閱讀 209評(píng)論 0 0