关键系统的JVM参数推荐
前言2, -XX:+PrintFlagsFinal打印參數(shù)值
當(dāng)你在網(wǎng)上興沖沖找到一個(gè)可優(yōu)化的參數(shù)時(shí),先打印看看,它可能已經(jīng)默認(rèn)打開(kāi)了,再找到一個(gè),還是默認(rèn)打開(kāi)了...
JDK7與JDK8,甚至JDK7中的不同小版本,有些參數(shù)值都不一樣,所以不要輕信網(wǎng)上任何文章,一切以生產(chǎn)環(huán)境同版本的JDK打出來(lái)的為準(zhǔn)。
經(jīng)常以類(lèi)似下面的語(yǔ)句去查看參數(shù),偷懶不起應(yīng)用,用-version代替。有些參數(shù)設(shè)置后會(huì)影響其他參數(shù),所以也得帶上。
java ?-XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -version| grep GCThreads
對(duì)于不同版本里的默認(rèn)值,建議是順勢(shì)而為,JDK在那個(gè)版本默認(rèn)打開(kāi)不打開(kāi)總有它的理由。安全第一,沒(méi)有很好的因由,不要隨便因?yàn)榫W(wǎng)上某篇文章的推薦(包括你現(xiàn)在在讀的這篇)就去設(shè)置。
?
1. 性能篇
1.1 建議的性能參數(shù)
1. 取消偏向鎖: -XX:-UseBiasedLocking
JDK1.6開(kāi)始默認(rèn)打開(kāi)的偏向鎖,會(huì)嘗試把鎖賦給第一個(gè)訪問(wèn)它的線(xiàn)程,取消同步塊上的synchronized原語(yǔ)。如果始終只有一條線(xiàn)程在訪問(wèn)它,就成功略過(guò)同步操作以獲得性能提升。
但一旦有第二條線(xiàn)程訪問(wèn)這把鎖,JVM就要撤銷(xiāo)偏向鎖恢復(fù)之前的狀態(tài),如果打開(kāi)安全點(diǎn)日志,可以看到不少RevokeBiasd的紀(jì)錄,像GC一樣Stop The World的干活,雖然只是很短的停頓,但對(duì)于多線(xiàn)程并發(fā)的應(yīng)用,取消掉它反而有性能的提升,所以Cassandra就取消了它。?
2. 加大Integer Cache: -XX:AutoBoxCacheMax=20000
Integer i=3;這語(yǔ)句有著 int自動(dòng)裝箱成Integer的過(guò)程,JDK默認(rèn)只緩存 -128 ~ +127的Integer 和 Long,超出范圍的數(shù)字就要即時(shí)構(gòu)建新的Integer對(duì)象。設(shè)為20000后,我們應(yīng)用的QPS有足足4%的提升。為什么是2萬(wàn)呢,因?yàn)?XX:+AggressiveOpts里也是這個(gè)值。 詳見(jiàn)《Java Integer(-128~127)值的==和equals比較產(chǎn)生的思考》。?
3. 啟動(dòng)時(shí)訪問(wèn)并置零內(nèi)存頁(yè)面: -XX:+AlwaysPreTouch
啟動(dòng)時(shí)就把參數(shù)里說(shuō)好了的內(nèi)存全部舔一遍,可能令得啟動(dòng)時(shí)慢上一點(diǎn),但后面訪問(wèn)時(shí)會(huì)更流暢,比如頁(yè)面會(huì)連續(xù)分配,比如不會(huì)在晉升老生代時(shí)才去訪問(wèn)頁(yè)面使得GC停頓時(shí)間加長(zhǎng)。ElasticSearch和Cassandra都打開(kāi)了它。?
4. SecureRandom生成加速: -Djava.security.egd=file:/dev/./urandom
此江湖偏方原因是Tomcat的SecureRandom顯式使用SHA1PRNG算法時(shí),初始因子默認(rèn)從/dev/random讀取會(huì)存在堵塞。額外效果是SecureRandom的默認(rèn)算法也變成更合適的SHA1了。詳見(jiàn) 《SecureRandom的江湖偏方與真實(shí)效果》?
1.2 可選的性能參數(shù)
1. -XX:+PerfDisableSharedMem
Cassandra家的一個(gè)參數(shù),一直沒(méi)留意,直到發(fā)生高IO時(shí)的JVM停頓。原來(lái)JVM經(jīng)常會(huì)默默的在/tmp/hperf?目錄寫(xiě)上一點(diǎn)statistics數(shù)據(jù),如果剛好遇到PageCache刷盤(pán),把文件阻塞了,就不能結(jié)束這個(gè)Stop the World的安全點(diǎn)了。
禁止JVM寫(xiě)statistics數(shù)據(jù)的代價(jià),是jps和jstat 用不了,只能用JMX,而JMX取新老生代的使用百分比還真沒(méi)jstat方便,VJTools的vjmxcli彌補(bǔ)了這一點(diǎn)。詳見(jià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é)?#xff0c;永遠(yuǎn)都達(dá)不到觸發(fā)C2編譯的1萬(wàn)次的閥值。
3. -XX:-TieredCompilation
多層編譯是JDK8后默認(rèn)打開(kāi)的比較驕傲的功能,先以C1靜態(tài)編譯,采樣足夠后C2編譯。
但我們實(shí)測(cè),性能最終略降2%,可能是因?yàn)橛行┓椒–1編譯后C2不再編譯了。應(yīng)用啟動(dòng)時(shí)的偶發(fā)服務(wù)超時(shí)也多了,可能是忙于編譯。所以我們將它禁止了,但記得打開(kāi)前面的-XX:-UseCounterDecay,避免有些溫?zé)岬姆椒ㄓ肋h(yuǎn)都要解釋執(zhí)行。
?
1.3 不建議的性能參數(shù)
1. -XX:+AggressiveOpts
一些還沒(méi)默認(rèn)打開(kāi)的優(yōu)化參數(shù)集合,?-XX:AutoBoxCacheMax是其中的一項(xiàng)。但如前所述,關(guān)鍵系統(tǒng)里不建議打開(kāi)。雖然通過(guò)-XX:+AggressiveOpts?與?-XX:-AggressiveOpts?的對(duì)比,目前才改變了三個(gè)參數(shù),但為免以后某個(gè)版本的JDK里默默改變更多激進(jìn)的配置,還是不要打開(kāi)了。
2. JIT Compile相關(guān)的參數(shù),函數(shù)調(diào)用多少次之后開(kāi)始編譯的閥值,內(nèi)聯(lián)函數(shù)大小的閥值等等,不要亂改。
3.?-server,在64位多核的linux中,你想設(shè)成-client都不行的,所以寫(xiě)了也是白寫(xiě)。?
2. 內(nèi)存與GC篇
2.1 GC策略
為了穩(wěn)健,還是8G以下的堆還是CMS好了,G1現(xiàn)在雖然是默認(rèn)了,但其實(shí)在小堆里的表現(xiàn)也沒(méi)有比CMS好,還是JDK11的ZGC引人期待。
1.CMS基本寫(xiě)法
-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly
因?yàn)槲覀兊谋O(jiān)控系統(tǒng)會(huì)通過(guò)JMX監(jiān)控內(nèi)存達(dá)到90%的狀況,所以設(shè)置讓它75%就開(kāi)始跑了,早點(diǎn)開(kāi)始也能減少Full GC等意外情況(概念重申,這種主動(dòng)的CMS GC,和JVM的老生代、永久代、堆外內(nèi)存完全不能分配內(nèi)存了而強(qiáng)制Full GC是不同的概念)。為了讓這個(gè)設(shè)置生效,還要設(shè)置UseCMSInitiatingOccupancyOnly,否則75%只被用來(lái)做開(kāi)始的參考值,后來(lái)還是JVM自己算。?
2. -XX:MaxTenuringThreshold=2
這是改動(dòng)效果最明顯的一個(gè)參數(shù)了。對(duì)象在Survivor區(qū)最多熬過(guò)多少次Young GC后晉升到年老代,JDK8里CMS 默認(rèn)是6,其他如G1是15。
Young GC是最大的應(yīng)用停頓來(lái)源,而YGC后存活對(duì)象的多少又直接影響停頓的時(shí)間,所以如果清楚Young GC的執(zhí)行頻率和應(yīng)用里大部分臨時(shí)對(duì)象的最長(zhǎng)生命周期,可以把它設(shè)的更短一點(diǎn),讓其實(shí)不是臨時(shí)對(duì)象的新生代對(duì)象趕緊晉升到年老代,別呆著。
用-XX:+PrintTenuringDistribution觀察下,如果后面幾代的大小總是差不多,證明過(guò)了某個(gè)年齡后的對(duì)象總能晉升到老生代,就可以把晉升閾值設(shè)小,比如JMeter里2就足夠了。?
3. -XX:+ExplicitGCInvokesConcurrent 但不要加-XX:+DisableExplicitGC
讓full gc時(shí)使用CMS算法,不是全程停頓,必選。
但像R大說(shuō)的,System GC是保護(hù)機(jī)制(如堆外內(nèi)存滿(mǎn)時(shí)清理它的堆內(nèi)引用對(duì)象),禁了system.gc() 未必是好事,只要沒(méi)用什么特別爛的類(lèi)庫(kù),真有人調(diào)了總有調(diào)的原因,所以不應(yīng)該加這個(gè)爛大街的參數(shù)。?
4.?-XX:+ParallelRefProcEnabled 和?-XX:+CMSParallelInitialMarkEnabled
并行的處理Reference對(duì)象,如WeakReference,默認(rèn)為false,除非在GC log里出現(xiàn)Reference處理時(shí)間較長(zhǎng)的日志,否則效果不會(huì)很明顯,但我們總是要JVM盡量的并行,所以設(shè)了也就設(shè)了。同理還有-XX:+CMSParallelInitialMarkEnabled,JDK8已默認(rèn)開(kāi)啟,但小版本比較低的JDK7甚至不支持。?
5. ParGCCardsPerStrideChunk
Linkined的黑科技, 2016版不建議打開(kāi),后來(lái)發(fā)現(xiàn)有些場(chǎng)景的確能減少YGC時(shí)間,詳見(jiàn)《難道他們說(shuō)的都是真的》,簡(jiǎn)單說(shuō)就是影響YGC時(shí)掃描老生代的時(shí)間,默認(rèn)值256太小了,但32K也未必對(duì),需要自己試驗(yàn)。
-XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=1024?
2.2 可選的GC參數(shù)
1. 并發(fā)收集線(xiàn)程數(shù)
ParallelGCThreads=8+( Processor - 8 ) ( 5/8 );ConcGCThreads = (ParallelGCThreads + 3)/4
比如雙CPU,六核,超線(xiàn)程就是24個(gè)處理器,小于8個(gè)處理器時(shí)ParallelGCThreads按處理器數(shù)量,大于時(shí)按上述公式Y(jié)GC線(xiàn)程數(shù)=18, CMS GC線(xiàn)程數(shù)=5。
CMS GC線(xiàn)程數(shù)的公式太怪,也有人提議簡(jiǎn)單改為YGC線(xiàn)程數(shù)的1/2。
一些不在乎停頓時(shí)間的后臺(tái)輔助程序,比如日志收集的logstash,建議把它減少到2,避免在GC時(shí)突然占用太多CPU核,影響主應(yīng)用。
而另一些并不獨(dú)占服務(wù)器的應(yīng)用,比如旁邊跑著一堆sidecar的,也建議減少YGC線(xiàn)程數(shù)。
一個(gè)真實(shí)的案例,24核的服務(wù)器,默認(rèn)18條YGC線(xiàn)程,因?yàn)榕赃呌袀€(gè)繁忙的Service Mesh Proxy在跑著,這18條線(xiàn)程并不能100%的搶到CPU,出現(xiàn)了不合理的慢GC,把線(xiàn)程數(shù)降低到12條反而更快了。 所以那些貪心的把YGC線(xiàn)程數(shù)=CPU 核數(shù)的,通常弄巧成拙。?
2. -XX:-CMSClassUnloadingEnabled
在CMS中清理永久代中的過(guò)期的Class而不等到Full GC,JDK7默認(rèn)關(guān)閉而JDK8打開(kāi)。看自己情況,比如有沒(méi)有運(yùn)行動(dòng)態(tài)語(yǔ)言腳本如Groovy產(chǎn)生大量的臨時(shí)類(lèi)。它有時(shí)會(huì)大大增加CMS GC的暫停時(shí)間。所以如果新類(lèi)加載并不頻繁,這個(gè)參數(shù)還是顯式關(guān)閉的好。?
3. -XX:+CMSScavengeBeforeRemark
默認(rèn)為關(guān)閉,在CMS remark前,先執(zhí)行一次minor GC將新生代清掉,這樣從老生代的對(duì)象引用到的新生代對(duì)象的個(gè)數(shù)就少了,停止全世界的CMS remark階段就短一些。但如果打開(kāi)了,會(huì)讓一次YGC緊接著一次CMS GC,使得停頓的總時(shí)間加長(zhǎng)了。
又一個(gè)真實(shí)案例,CMS GC的時(shí)間和新生代的使用量成比例,新生代較小時(shí)很快完成,新生代快滿(mǎn)時(shí)CMS GC的停頓時(shí)間超過(guò)2秒,這時(shí)候就還是打開(kāi)了劃算。
?
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%,堆外內(nèi)存滿(mǎn),老生代碎片過(guò)大無(wú)法分配空間給新晉升的大對(duì)象這些特殊情況里發(fā)生,所以設(shè)為每次都進(jìn)行碎片整理是合適的,詳見(jiàn)此貼里R大的解釋。
?3.-XX:+GCLockerInvokesConcurrent
我們犯過(guò)的錯(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)存,線(xiàn)程棧,永久代,二進(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的頻率,如果老生代里沒(méi)多少長(zhǎng)期對(duì)象的話(huà),占2/3通常太多了。可以用-Xmn 直接賦值(等于-XX:NewSize and -XX:MaxNewSize同值的縮寫(xiě)),或把NewRatio設(shè)為1來(lái)對(duì)半分。
?3. -XX: PermSize=128m -XX:MaxPermSize=512m (JDK7)-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m(JDK8)
現(xiàn)在的應(yīng)用有Hibernate/Spring這些鬧騰的家伙AOP之后類(lèi)都比較多,可以一開(kāi)始就把初始值從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
在堆之外,線(xiàn)程占用棧內(nèi)存,默認(rèn)每條線(xiàn)程為1M(以前是256K)。存放方法調(diào)用出參入?yún)⒌臈?#xff0c;局部變量,標(biāo)量替換后掉局部變量等,有人喜歡把它設(shè)回256k如Cassandra,節(jié)約內(nèi)存并開(kāi)更多線(xiàn)程,有人則會(huì)在遇到錯(cuò)誤后把它再設(shè)大點(diǎn),特別是有很深的JSON解析之類(lèi)的遞歸調(diào)用時(shí)。?
2. -XX:SurvivorRatio
新生代中每個(gè)存活區(qū)的大小,默認(rèn)為8,即1/10的新生代 1/(SurvivorRatio+2),有人喜歡設(shè)小點(diǎn)省點(diǎn)給新生代,但要避免太小使得存活區(qū)放不下臨時(shí)對(duì)象而被迫晉升到老生代,還是從GC日志里看實(shí)際情況了。?
3. -XX:MaxDirectMemorySize
堆外內(nèi)存的最大值,默認(rèn)為Heap區(qū)總內(nèi)存減去一個(gè)Survivor區(qū)的大小,詳見(jiàn)《Netty之堆外內(nèi)存掃盲篇》,如果肯定用不了這么多,也可以把它主動(dòng)設(shè)小,來(lái)獲得一個(gè)比較清晰內(nèi)存占用預(yù)估值,特別是在容器里。?
4. -XX:ReservedCodeCacheSize
JIT編譯后二進(jìn)制代碼的存放區(qū),滿(mǎn)了之后就不再編譯,對(duì)性能影響很大。 JDK7默認(rèn)不開(kāi)多層編譯48M,開(kāi)了96M,而JDK8默認(rèn)開(kāi)多層編譯240M。可以在JMX里看看CodeCache的占用情況,也可以用VJTools里的vjtop來(lái)看,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,將來(lái)有據(jù)可查。打印出來(lái)的是命令行里設(shè)置了的參數(shù)以及因?yàn)檫@些參數(shù)隱式影響的參數(shù),比如開(kāi)了CMS后,-XX:+UseParNewGC也被自動(dòng)打開(kāi)。?
2. -XX:-OmitStackTraceInFastThrow
為異常設(shè)置StackTrace是個(gè)昂貴的操作,所以當(dāng)應(yīng)用在相同地方拋出相同的異常N次(兩萬(wàn)?)之后,JVM會(huì)對(duì)某些特定異常如NPE,數(shù)組越界等進(jìn)行優(yōu)化,不再帶上異常棧。此時(shí),你可能會(huì)看到日志里一條條Nul Point Exception,而之前輸出完整棧的日志早被滾動(dòng)到不知哪里去了,也就完全不知道這NPE發(fā)生在什么地方,欲哭無(wú)淚。 所以,將它禁止吧,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=${LOGDIR}/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有什么用?看來(lái)你是沒(méi)遇過(guò)JVM Segment Fault的幸福人。?
3. -XX:+HeapDumpOnOutOfMemoryError(可選)
在Out Of Memory,JVM快死掉的時(shí)候,輸出Heap Dump到指定文件。不然開(kāi)發(fā)很多時(shí)候還真不知道怎么重現(xiàn)錯(cuò)誤。
路徑只指向目錄,JVM會(huì)保持文件名的唯一性,叫java_pid${pid}.hprof。因?yàn)槿绻赶蛭募?#xff0c;而文件已存在,反而不能寫(xiě)入。
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGDIR}/
但在容器環(huán)境下,輸出4G的HeapDump,在普通硬盤(pán)上會(huì)造成20秒以上的硬盤(pán)IO跑滿(mǎn),也是個(gè)十足的惡鄰,影響了同一宿主機(jī)上所有其他的容器。
?
3.3 GC日志
JDK9完全不一樣了,這里還是寫(xiě)JDK7/8的配置。
1.基本配置
-Xloggc:/dev/shm/gc-myapp.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails
有人擔(dān)心寫(xiě)GC日志會(huì)影響性能,但測(cè)試下來(lái)實(shí)在沒(méi)什么影響,GC問(wèn)題是Java里最常見(jiàn)的問(wèn)題,沒(méi)日志怎么行。
后來(lái)又發(fā)現(xiàn)如果遇上高IO的情況,GC時(shí)操作系統(tǒng)正在flush pageCache 到磁盤(pán)的話(huà),也可能導(dǎo)致GC log文件被鎖住,從而讓GC結(jié)束不了。所以把它指向了/dev/shm 這種內(nèi)存中文件系統(tǒng),避免這種停頓,詳見(jiàn)《Eliminating Large JVM GC Pauses Caused by Background IO Traffic》
用PrintGCDateStamps而不是PrintGCTimeStamps,打印可讀的日期而不是時(shí)間戳。
?2. -XX:+PrintGCApplicationStoppedTime
這是個(gè)非常非常重要的參數(shù),它的名字沒(méi)起好,它除了打印清晰的完整的GC停頓時(shí)間外,還可以打印其他的JVM停頓時(shí)間,比如取消偏向鎖,class 被agent redefine,code deoptimization等等,有助于發(fā)現(xiàn)一些原來(lái)沒(méi)想到的問(wèn)題,建議也加上。如果真的發(fā)現(xiàn)了一些不知是什么的停頓,需要打印安全點(diǎn)日志找原因。
?3. -XX:+PrintGCCause
打印產(chǎn)生GC的原因,比如AllocationFailure什么的,在JDK8已默認(rèn)打開(kāi),JDK7要顯式打開(kāi)一下。
?4. -XX:+PrintPromotionFailure
打開(kāi)了就知道是多大的新生代對(duì)象晉升到老生代失敗從而引發(fā)Full GC時(shí)的。
?5. GC日志滾動(dòng)與備份
GC日志默認(rèn)會(huì)在重啟后清空,有人擔(dān)心長(zhǎng)期運(yùn)行的應(yīng)用會(huì)把文件弄得很大,所以"-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M"的參數(shù)可以讓日志滾動(dòng)起來(lái)。但真用起來(lái)重啟后的文件名太混亂太讓人頭痛,GC日志再大也達(dá)不到哪里去,所以我們沒(méi)有加滾動(dòng),并且自行在啟動(dòng)腳本里對(duì)舊日志做備份。
?
3.4 安全點(diǎn)日志
如果GC日志里有非GC的JVM停頓時(shí)間,你得打出安全點(diǎn)日志來(lái)知道詳情,詳見(jià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之類(lèi)監(jiān)控軟件通過(guò)JMX監(jiān)控JVM,不允許遠(yuǎn)程訪問(wèn)。
如果應(yīng)用忘記了加上述參數(shù),又不想改參數(shù)重啟服務(wù),可以用VJTools的vjmxcli來(lái)救急,它能通過(guò)PID直接連入目標(biāo)JVM打開(kāi)JMX。
?
4. 小結(jié)
謝謝大家看到這里,上文的所有內(nèi)容,其實(shí)都在VJTools的?jvm-options.sh 里面了。如果覺(jué)得能省了大家的時(shí)間,麻煩給項(xiàng)目點(diǎn)個(gè)Star。
轉(zhuǎn)載于:https://blog.51cto.com/jack88/2369035
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的关键系统的JVM参数推荐的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: rhel6 上udev的绑定
- 下一篇: java信息管理系统总结_java实现科