歡迎關(guān)注公眾號OpenCoder甘邀,來和我做朋友吧~??????
就目前大部分互聯(lián)網(wǎng)創(chuàng)業(yè)型公司,其開發(fā)的系統(tǒng)幾乎都不會考慮JVM性能優(yōu)化這一塊昔字,哪怕一個團隊中有1個技術(shù)Leader或架構(gòu)師爆袍,往往都沒有太多精力去把控到特別細節(jié)的地方上,以及對JVM也沒有那么的精通與熟悉,這也導(dǎo)致一個很大的問題螃宙,大部分工程師開發(fā)完一個系統(tǒng)后蛮瞄,部署生產(chǎn)環(huán)境的時候根本對JVM參數(shù)什么的設(shè)置一竅不通,也就是默認的JVM參數(shù)進行系統(tǒng)的運行谆扎,等系統(tǒng)在某個時段出現(xiàn)問題后挂捅,開始大量分析找bug,很久也未能找出什么原因堂湖。
默認的JVM參數(shù)絕對是系統(tǒng)負載逐漸增高的時候一個最大的問題
如果你不設(shè)置-Xmx闲先、-Xms之類的堆內(nèi)存大小的話,你啟動一個系統(tǒng)无蜂,可能默認就給你幾百MB的堆內(nèi)存大小伺糠,新生代和老年代可能都是幾百MB的樣子。新生代內(nèi)存過小斥季,會導(dǎo)致Survivor區(qū)域內(nèi)存過小训桶,同時Eden區(qū)域也很小。Eden區(qū)域過小酣倾,自然會導(dǎo)致頻繁的觸發(fā)Young GC舵揭,Survivor區(qū)域過小,自然會導(dǎo)致經(jīng)常在Young GC之后存活對象其實也沒多少躁锡,但就是Survivor區(qū)域放不下午绳。此時必然會導(dǎo)致對象經(jīng)常進入老年代中,因此也必然會導(dǎo)致老年代過一段時間就放滿了映之,然后就會觸發(fā)Full GC拦焚。
因此在大部分工程師都對JVM優(yōu)化不是很精通的情況下,而你作為技術(shù)Leader或架構(gòu)師杠输,通過推行一個JVM參數(shù)模板赎败,可以讓各個系統(tǒng)短時間內(nèi)迅速優(yōu)化JVM的性能。
這里強調(diào)一點:沒有絕對的模板蠢甲,任何系統(tǒng)的實際運行情況以及生產(chǎn)環(huán)境都不一樣螟够,因此不能直接想著萬能模板解決,而是真正自己通過分析JVM的運行情況峡钓,內(nèi)存占比妓笙,GC頻率去準(zhǔn)確的進行優(yōu)化!
這里我們僅僅是針對中小型公司能岩,一些完全不懂JVM參數(shù)優(yōu)化的團隊寞宫,給出一個標(biāo)準(zhǔn)的模板進行優(yōu)化,總比直接使用默認JVM參數(shù)要好很多拉鹃!然后盡量讓大部分系統(tǒng)套用這個模板辈赋,基本保證JVM性能別太差鲫忍,避免很多初中級工程師直接使用默認的JVM參數(shù),可能一臺8G內(nèi)存的機器上钥屈,JVM堆內(nèi)存就分配了幾百MB悟民。
模板參數(shù):
-Xms4096M
-Xmx4096M
-Xmn3072M
-Xss1M
-XX:PermSize=256M
-XX:MaxPermSize=256M
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=92
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
參數(shù)設(shè)置解釋:
一般來講線上部署的機器都差不多是8G4核,那么分配4G給JVM內(nèi)存也就足夠了篷就,畢竟還有其他一些進程需要使用到內(nèi)存射亏,然后新生代分配了3G,盡量讓新生代大一些竭业!進而對應(yīng)的Survivor區(qū)域能分配到300MB智润。
不同的系統(tǒng)運行的狀況不同,基本上每次minor gc 過后存活幾十MB對象是常態(tài)未辆,因此幾十MB對象進入Survivor區(qū)還是很輕松的窟绷,也不會輕易觸發(fā) 動態(tài)年齡判定規(guī)則,讓部分對象直接進老年代咐柜。
只要內(nèi)存分配合理兼蜈,那么進入老年代的對象就很少或極慢,該參數(shù)模板在多個系統(tǒng)的測試下拙友,通過jstat觀察饭尝,基本上各個系統(tǒng)的Full GC都在幾天發(fā)生一次。
-XX:CMSFullGCsBeforeCompaction=0該參數(shù)的設(shè)置也是非常重要献宫,保證了我們每次Full GC之后都會執(zhí)行一次內(nèi)存整理,解決內(nèi)存碎片的問題实撒。
進一步性能優(yōu)化:
這里我們再介紹兩個參數(shù)姊途,可以幫助優(yōu)化Full GC的性能,把每次Full GC的時間進一步降低一些知态。
第一個參數(shù):-XX:+CMSParallelInitialMarkEnabled捷兰,這個參數(shù)會在CMS垃圾回收器的“初始標(biāo)記”階段開啟多線程并發(fā)執(zhí)行。
因為初始標(biāo)記階段负敏,我們之前說過是會進入STW的贡茅,導(dǎo)致系統(tǒng)停頓,所以這個階段如果能多線程并發(fā)執(zhí)行其做,可以有效提升標(biāo)記的效率顶考,減少STW的時間。
第二個參數(shù):-XX:+CMSScavengeBeforeRemark妖泄,這個參數(shù)會在CMS的重新標(biāo)記階段之前驹沿,先盡量執(zhí)行一次Young GC。
CMS的重新標(biāo)記階段也是會進入STW的蹈胡,所以如果在重新標(biāo)記之前渊季,先執(zhí)行一次Young GC朋蔫,就會回收掉一些年輕代里沒有人引用的對象。所以如果先提前回收掉一些對象却汉,那么在CMS的重新標(biāo)記階段就可以少掃描一些對象驯妄,此時就可以提升CMS的重新標(biāo)記階段的性能,減少他的耗時合砂。
加入兩個參數(shù)后的整體JVM參數(shù)模板:
-Xms4096M
-Xmx4096M
-Xmn3072M
-Xss1M
-XX:PermSize=256M
-XX:MaxPermSize=256M
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=92
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSParallelInitialMarkEnabled
-XX:+CMSScavengeBeforeRemark
ok青扔,那么以上JVM參數(shù)模板就給到大家了,后續(xù)開發(fā)中可以直接進行使用既穆。哪怕是不太懂JVM優(yōu)化的普通工程師只要套用這個模板赎懦,對一些普通的業(yè)務(wù)系統(tǒng),都能保證其JVM性能不會出現(xiàn)大的問題幻工,比如頻繁的Young GC和Full GC導(dǎo)致的系統(tǒng)頻繁卡頓励两。