- JVM參數(shù)的含義
參數(shù)名稱 | 含義 | 默認(rèn)值 | 說明 |
---|---|---|---|
-Xms | 初始堆大小 | 物理內(nèi)存的1/64(<1GB) | 默認(rèn)(MinHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存小于40%時(shí)舌狗,JVM就會(huì)增大堆直到-Xmx的最大限制. |
-Xmx | 最大堆大小 | 物理內(nèi)存的1/4(<1GB) | 默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆直到 -Xms的最小限制 |
-Xmn | 年輕代大小(1.4 or later) | 此處的大小是(eden+ 2 survivor space)與jmap -heap中顯示的New gen是不同的寸齐。 | 整個(gè)堆大小=年輕代大小 + 年老代大小 + 持久代大小塞帐,增大年輕代后,將會(huì)減小年老代大小.此值對(duì)系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)堆的3/8 |
-XX:NewSize | 設(shè)置年輕代大小(for 1.3/1.4) | ||
-XX:MaxNewSize | 年輕代最大值(for 1.3/1.4) | ||
-XX:PermSize | 設(shè)置持久代(perm gen)初始值 | 物理內(nèi)存的1/64 | |
-XX:MaxPermSize | 設(shè)置持久代最大值 | 物理內(nèi)存的1/4 | |
-Xss | 每個(gè)線程的堆棧大小 | JDK5.0以后每個(gè)線程堆棧大小為1M宜肉,以前每個(gè)線程堆棧大小為256K橘霎。 | 根據(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左右统捶。一般小的應(yīng)用, 如果棧不是很深柄粹, 應(yīng)該是128k夠用的喘鸟,大的應(yīng)用建議使用256k。這個(gè)選項(xiàng)對(duì)性能影響比較大驻右,需要嚴(yán)格的測試什黑。和threadStackSize選項(xiàng)解釋很類似:-Xss is translated in a VM flag named ThreadStackSize。 |
-XX:ThreadStackSize | Thread Stack Size | (0:使用默認(rèn)stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.] | |
-XX:NewRatio | 年輕代(包括Eden和兩個(gè)Survivor區(qū))與年老代的比值(除去持久代) | =4表示年輕代與年老代所占比值為1:4堪夭,年輕代占整個(gè)堆棧的1/5愕把。Xms=Xmx并且設(shè)置了Xmn的情況下,該參數(shù)不需要進(jìn)行設(shè)置森爽。 | |
-XX:SurvivorRatio | Eden區(qū)與Survivor區(qū)的大小比值 | 設(shè)置為8恨豁,則兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:8,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/10 | |
-XX:LargePageSizeInBytes | 內(nèi)存頁的大小不可設(shè)置過大爬迟, 會(huì)影響Perm的大小 | =128m | |
-XX:+UseFastAccessorMethods | 原始類型的快速優(yōu)化 | ||
-XX:+DisableExplicitGC | 關(guān)閉System.gc() | 這個(gè)參數(shù)需要嚴(yán)格的測試 | |
-XX:MaxTenuringThreshold | 垃圾最大年齡 | 如果設(shè)置為0的話橘蜜,則年輕代對(duì)象不經(jīng)過Survivor區(qū),直接進(jìn)入年老代付呕。 對(duì)于年老代比較多的應(yīng)用计福,可以提高效率。如果將此值設(shè)置為一個(gè)較大值徽职,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制象颖,這樣可以增加對(duì)象再年輕代的存活時(shí)間,增加在年輕代即被回收的概率姆钉。該參數(shù)只有在串行GC時(shí)才有效说订。 | |
-XX:+AggressiveOpts | 加快編譯 | ||
-XX:+UseBiasedLocking | 鎖機(jī)制的性能改善 | ||
-Xnoclassgc | 禁用垃圾回收 | ||
-XX:SoftRefLRUPolicyMSPerMB | 每兆堆空閑空間中SoftReference的存活時(shí)間 | 1s | softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap |
-XX:PretenureSizeThreshold | 對(duì)象超過多大是直接在老年代分配 | 0 | 單位:字節(jié)。新生代采用Parallel Scavenge GC時(shí)無效育韩,另一種直接在老年代分配的情況是大的數(shù)組對(duì)象克蚂,且數(shù)組中無外部引用對(duì)象。 |
-XX:TLABWasteTargetPercent | TLAB占eden區(qū)的百分比 | 1% | |
-XX:+CollectGen0First | FullGC時(shí)是否先YGC | false |
- 并行收集器相關(guān)參數(shù)
參數(shù)名稱 | 含義 | 默認(rèn)值 | 說明 |
---|---|---|---|
-XX:+UseParallelGC | Full GC采用parallel MSC | 選擇垃圾收集器為并行收集器筋讨,此配置僅對(duì)年輕代有效埃叭。即上述配置下,年輕代使用并發(fā)收集悉罕,而年老代仍舊使用串行收集赤屋。(待驗(yàn)證) | |
-XX:+UseParNewGC | 設(shè)置年輕代為并行收集 | 可與CMS收集同時(shí)使用立镶。JDK5.0以上,JVM會(huì)根據(jù)系統(tǒng)配置自行設(shè)置类早,所以無需再設(shè)置此值 | |
-XX:ParallelGCThreads | 并行收集器的線程數(shù) | 此值最好配置與處理器數(shù)目相等媚媒,同樣適用于CMS | |
-XX:+UseParallelOldGC | 年老代垃圾收集方式為并行收集(Parallel Compacting) | 這個(gè)是JAVA 6出現(xiàn)的參數(shù)選項(xiàng) | |
-XX:MaxGCPauseMillis | 每次年輕代垃圾回收的最長時(shí)間(最大暫停時(shí)間) | 如果無法滿足此時(shí)間,JVM會(huì)自動(dòng)調(diào)整年輕代大小涩僻,以滿足此值缭召。 | |
-XX:+UseAdaptiveSizePolicy | 自動(dòng)選擇年輕代區(qū)大小和相應(yīng)的Survivor區(qū)比例 | 設(shè)置此選項(xiàng)后,并行收集器會(huì)自動(dòng)選擇年輕代區(qū)大小和相應(yīng)的Survivor區(qū)比例逆日,以達(dá)到目標(biāo)系統(tǒng)規(guī)定的最低相應(yīng)時(shí)間或者收集頻率等嵌巷,此值建議使用并行收集器時(shí),一直打開室抽。 | |
-XX:GCTimeRatio | 設(shè)置垃圾回收時(shí)間占程序運(yùn)行時(shí)間的百分比 | 公式為1/(1+n) | |
-XX:+ScavengeBeforeFullGC | Full GC前調(diào)用YGC | true | Do young generation GC prior to a full GC. (Introduced in 1.4.1.) |
- CMS相關(guān)參數(shù)
參數(shù)名稱 | 含義 | 默認(rèn)值 | 說明 |
---|---|---|---|
-XX:+UseConcMarkSweepGC | 使用CMS內(nèi)存收集 | 測試中配置這個(gè)以后搪哪,-XX:NewRatio=4的配置失效了,原因不明坪圾。所以晓折,此時(shí)年輕代大小最好用-Xmn設(shè)置。 | |
-XX:+AggressiveHeap | 試圖是使用大量的物理內(nèi)存長時(shí)間大內(nèi)存使用的優(yōu)化兽泄,能檢查計(jì)算資源(內(nèi)存漓概, 處理器數(shù)量)至少需要256MB內(nèi)存大量的CPU/內(nèi)存, (在1.4.1在4CPU的機(jī)器上已經(jīng)顯示有提升) | ||
-XX:CMSFullGCsBeforeCompaction | 多少次后進(jìn)行內(nèi)存壓縮 | 由于并發(fā)收集器不對(duì)內(nèi)存空間進(jìn)行壓縮整理已日,所以運(yùn)行一段時(shí)間以后會(huì)產(chǎn)生"碎片"垛耳,使得運(yùn)行效率降低。此值設(shè)置運(yùn)行多少次GC以后對(duì)內(nèi)存空間進(jìn)行壓縮整理飘千。 | |
-XX:+CMSParallelRemarkEnabled | 降低標(biāo)記停頓 | ||
-XX+UseCMSCompactAtFullCollection | 在FULL GC的時(shí)候堂鲜, 對(duì)年老代的壓縮 | CMS是不會(huì)移動(dòng)內(nèi)存的, 非常容易產(chǎn)生碎片护奈, 導(dǎo)致內(nèi)存不夠用缔莲, 因此, 內(nèi)存的壓縮這個(gè)時(shí)候就會(huì)被啟用霉旗。 增加這個(gè)參數(shù)是個(gè)好習(xí)慣痴奏。可能會(huì)影響性能厌秒,但是可以消除碎片 | |
-XX:+UseCMSInitiatingOccupancyOnly | 使用手動(dòng)定義初始化定義開始CMS收集 | 禁止hostspot自行觸發(fā)CMS GC | |
-XX:CMSInitiatingOccupancyFraction=70 | 使用cms作為垃圾回收使用70%后開始CMS收集 | 92 | 為了保證不出現(xiàn)promotion failed錯(cuò)誤读拆,該值的設(shè)置需要滿足以下公式CMSInitiatingOccupancyFraction計(jì)算公式 |
-XX:CMSInitiatingPermOccupancyFraction | 設(shè)置Perm Gen使用到達(dá)多少比率時(shí)觸發(fā) | 92 | |
-XX:+CMSIncrementalMode | 設(shè)置為增量模式 | 用于單CPU情況 | |
-XX:+CMSClassUnloadingEnabled |
- 輔助信息
參數(shù)名稱 | 含義 | 默認(rèn)值 | 說明 |
---|---|---|---|
-XX:+PrintGC | 輸出形式:[GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K), 0.0650971 secs] | ||
-XX:+PrintGCDetails | 輸出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs] | ||
-XX:+PrintGCTimeStamps | |||
-XX:+PrintGC:PrintGCTimeStamps | 可與-XX:+PrintGC -XX:+PrintGCDetails混合使用 | 輸出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs] | |
-XX:+PrintGCApplicationStoppedTime | 打印垃圾回收期間程序暫停的時(shí)間,可與上面混合使用 | 輸出形式:Total time for which application threads were stopped: 0.0468229 seconds | |
-XX:+PrintGCApplicationConcurrentTime | 打印每次垃圾回收前鸵闪,程序未中斷的執(zhí)行時(shí)間檐晕。可與上面混合使用 | 輸出形式:Application time: 0.5291524 seconds | |
-XX:+PrintHeapAtGC | 打印GC前后的詳細(xì)堆棧信息 | ||
-Xloggc:filename | 把相關(guān)日志信息記錄到文件以便分析,與上面幾個(gè)配合使用 | ||
-XX:+PrintClassHistogram | garbage collects before printing the histogram. | ||
-XX:+PrintTLAB | 查看TLAB空間的使用情況 | ||
XX:+PrintTenuringDistribution | 查看每次minor GC后新的存活周期的閾值 | Desired survivor size 1048576 bytes, new threshold 7 (max 15) new threshold 7即標(biāo)識(shí)新的存活周期的閾值為7辟灰。 |
新生代GC策略 | 老年老代GC策略 | 說明 | |
---|---|---|---|
組合1 | Serial | Serial Old | Serial和Serial Old都是單線程進(jìn)行GC个榕,特點(diǎn)就是GC時(shí)暫停所有應(yīng)用線程。 |
組合2 | Serial | CMS+Serial Old | CMS(Concurrent Mark Sweep)是并發(fā)GC芥喇,實(shí)現(xiàn)GC線程和應(yīng)用線程并發(fā)工作西采,不需要暫停所有應(yīng)用線程。另外继控,當(dāng)CMS進(jìn)行GC失敗時(shí)械馆,會(huì)自動(dòng)使用Serial Old策略進(jìn)行GC。 |
組合3 | ParNew | CMS | 使用 -XX:+UseParNewGC選項(xiàng)來開啟武通。ParNew是Serial的并行版本狱杰,可以指定GC線程數(shù),默認(rèn)GC線程數(shù)為CPU的數(shù)量厅须。可以使用-XX:ParallelGCThreads選項(xiàng)指定GC的線程數(shù)食棕。如果指定了選項(xiàng) -XX:+UseConcMarkSweepGC選項(xiàng)朗和,則新生代默認(rèn)使用ParNew GC策略。 |
組合4 | ParNew | Serial Old | 使用 -XX:+UseParNewGC選項(xiàng)來開啟簿晓。新生代使用ParNew GC策略眶拉,年老代默認(rèn)使用Serial Old GC策略。 |
組合5 | Parallel Scavenge | Serial Old | Parallel Scavenge策略主要是關(guān)注一個(gè)可控的吞吐量:應(yīng)用程序運(yùn)行時(shí)間 / (應(yīng)用程序運(yùn)行時(shí)間 + GC時(shí)間)憔儿,可見這會(huì)使得CPU的利用率盡可能的高忆植,適用于后臺(tái)持久運(yùn)行的應(yīng)用程序,而不適用于交互較多的應(yīng)用程序谒臼。 |
組合6 | Parallel Scavenge | Parallel Old | Parallel Old是Serial Old的并行版本 |
組合7 | G1GC | G1GC | -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC #開啟朝刊; -XX:MaxGCPauseMillis=50 #暫停時(shí)間目標(biāo); -XX:GCPauseIntervalMillis=200 #暫停間隔目標(biāo)蜈缤; -XX:+G1YoungGenSize=512m #年輕代大惺懊ァ; -XX:SurvivorRatio=6 #幸存區(qū)比例 |
GC性能方面的考慮
對(duì)于GC的性能主要有2個(gè)方面的指標(biāo):吞吐量throughput(工作時(shí)間不算gc的時(shí)間占總的時(shí)間比)和暫停pause(gc發(fā)生時(shí)app對(duì)外顯示的無法響應(yīng))底哥。
1. Total Heap
默認(rèn)情況下咙鞍,vm會(huì)增加/減少heap大小以維持free space在整個(gè)vm中占的比例,這個(gè)比例 MinHeapFreeRatio
和MaxHeapFreeRatio
指定趾徽。
一般而言续滋,server端的app會(huì)有以下規(guī)則:
- 對(duì)vm分配盡可能多的memory;
- 將Xms和Xmx設(shè)為一樣的值孵奶。如果虛擬機(jī)啟動(dòng)時(shí)設(shè)置使用的內(nèi)存比較小疲酌,這個(gè)時(shí)候又需要初始化很多對(duì)象,虛擬機(jī)就必須重復(fù)地增加內(nèi)存拒课。
- 處理器核數(shù)增加徐勃,內(nèi)存也跟著增大事示。
2. The Young Generation
另外一個(gè)對(duì)于app流暢性運(yùn)行影響的因素是young generation的大小。young generation越大僻肖,minor collection越少肖爵;但是在固定heap size情況下,更大的young generation就意味著小的tenured generation臀脏,就意味著更多的major collection(major collection會(huì)引發(fā)minor collection)劝堪。
NewRatio反映的是young和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限揉稚,將這兩個(gè)值設(shè)為一樣就固定了young generation的大忻肜病(同Xms和Xmx設(shè)為一樣)。
如果希望搀玖,SurvivorRatio也可以優(yōu)化survivor的大小余境,不過這對(duì)于性能的影響不是很大。SurvivorRatio是eden和survior大小比例灌诅。
一般而言芳来,server端的app會(huì)有以下規(guī)則:
- 首先決定能分配給vm的最大的heap size,然后設(shè)定最佳的young generation的大胁率啊即舌;
- 如果heap size固定后,增加young generation的大小意味著減小tenured generation大小挎袜。讓tenured generation在任何時(shí)候夠大顽聂,能夠容納所有l(wèi)ive的data(留10%-20%的空余)。
經(jīng)驗(yàn)&&規(guī)則
-
年輕代大小選擇
- 響應(yīng)時(shí)間優(yōu)先的應(yīng)用:盡可能設(shè)大盯仪,直到接近系統(tǒng)的最低響應(yīng)時(shí)間限制(根據(jù)實(shí)際情況選擇)紊搪。在此種情況下,年輕代收集發(fā)生的頻率也是最小的全景。同時(shí)嗦明,減少到達(dá)年老代的對(duì)象。
- 吞吐量優(yōu)先的應(yīng)用:盡可能的設(shè)置大蚪燕,可能到達(dá)Gbit的程度娶牌。因?yàn)閷?duì)響應(yīng)時(shí)間沒有要求,垃圾收集可以并行進(jìn)行馆纳,一般適合8 CPU以上的應(yīng)用诗良。
- 避免設(shè)置過小。當(dāng)新生代設(shè)置過小時(shí)會(huì)導(dǎo)致:
- YGC次數(shù)更加頻繁
- 可能導(dǎo)致YGC對(duì)象直接進(jìn)入老年代鲁驶,如果此時(shí)老年代滿了鉴裹,會(huì)觸發(fā)FGC。
-
年老代大小選擇
1、響應(yīng)時(shí)間優(yōu)先的應(yīng)用:年老代使用并發(fā)收集器径荔,所以其大小需要小心設(shè)置督禽,一般要考慮并發(fā)會(huì)話率和會(huì)話持續(xù)時(shí)間等一些參數(shù)。如果堆設(shè)置小了总处,可以會(huì)造成內(nèi)存碎片狈惫,高回收頻率以及應(yīng)用暫停而使用傳統(tǒng)的標(biāo)記清除方式;如果堆大了鹦马,則需要較長的收集時(shí)間胧谈。最優(yōu)化的方案,一般需要參考以下數(shù)據(jù)獲得:并發(fā)垃圾收集信息荸频、持久代并發(fā)收集次數(shù)菱肖、傳統(tǒng)GC信息、花在年輕代和年老代回收上的時(shí)間比例旭从。
2稳强、吞吐量優(yōu)先的應(yīng)用:一般吞吐量優(yōu)先的應(yīng)用都有一個(gè)很大的年輕代和一個(gè)較小的年老代。原因是和悦,這樣可以盡可能回收掉大部分短期對(duì)象键袱,減少中期的對(duì)象,而年老代盡存放長期存活對(duì)象摹闽。
3、較小堆引起的碎片問題:因?yàn)槟昀洗牟l(fā)收集器使用標(biāo)記褐健,清除算法付鹿,所以不會(huì)對(duì)堆進(jìn)行壓縮。當(dāng)收集器回收時(shí)蚜迅,他會(huì)把相鄰的空間進(jìn)行合并舵匾,這樣可以分配給較大的對(duì)象。但是谁不,當(dāng)堆空間較小時(shí)坐梯,運(yùn)行一段時(shí)間以后,就會(huì)出現(xiàn)"碎片"刹帕,如果并發(fā)收集器找不到足夠的空間吵血,那么并發(fā)收集器將會(huì)停止,然后使用傳統(tǒng)的標(biāo)記偷溺,清除方式進(jìn)行回收蹋辅。如果出現(xiàn)"碎片",可能需要進(jìn)行如下配置:
-XX:+UseCMSCompactAtFullCollection : 使用并發(fā)收集器時(shí)挫掏,開啟對(duì)年老代的壓縮侦另。
-XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這里設(shè)置多少次Full GC后,對(duì)年老代進(jìn)行壓縮4褒傅、用64位操作系統(tǒng)弃锐,Linux下64位的jdk比32位jdk要慢一些,但是吃得內(nèi)存更多殿托,吞吐量更大
5霹菊、XMX和XMS設(shè)置一樣大,MaxPermSize和MinPermSize設(shè)置一樣大碌尔,這樣可以減輕伸縮堆大小帶來的壓力
6浇辜、使用CMS的好處是用盡量少的新生代,經(jīng)驗(yàn)值是128M-256M唾戚, 然后老生代利用CMS并行收集柳洋, 這樣能保證系統(tǒng)低延遲的吞吐效率。 實(shí)際上cms的收集停頓時(shí)間非常的短叹坦,2G的內(nèi)存熊镣, 大約20-80ms的應(yīng)用程序停頓時(shí)間
7、系統(tǒng)停頓的時(shí)候可能是GC的問題也可能是程序的問題募书,多用jmap和jstack查看绪囱,或者killall -3 java,然后查看java控制臺(tái)日志莹捡,能看出很多問題鬼吵。(相關(guān)工具的使用方法將在后面的blog中介紹)
8、仔細(xì)了解自己的應(yīng)用篮赢,如果用了緩存齿椅,那么年老代應(yīng)該大一些,緩存的HashMap不應(yīng)該無限制長启泣,建議采用LRU算法的Map做緩存涣脚,LRUMap的最大長度也要根據(jù)實(shí)際情況設(shè)定。
9寥茫、采用并發(fā)回收時(shí)遣蚀,年輕代小一點(diǎn),年老代要大纱耻,因?yàn)槟昀洗笥玫氖遣l(fā)回收芭梯,即使時(shí)間長點(diǎn)也不會(huì)影響其他程序繼續(xù)運(yùn)行,網(wǎng)站不會(huì)停頓
10弄喘、JVM參數(shù)的設(shè)置(特別是 –Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等參數(shù)的設(shè)置沒有一個(gè)固定的公式粥帚,需要根據(jù)PV old區(qū)實(shí)際數(shù)據(jù) YGC次數(shù)等多方面來衡量。為了避免promotion faild可能會(huì)導(dǎo)致xmn設(shè)置偏小限次,也意味著YGC的次數(shù)會(huì)增多芒涡,處理并發(fā)訪問的能力下降等問題柴灯。每個(gè)參數(shù)的調(diào)整都需要經(jīng)過詳細(xì)的性能測試,才能找到特定應(yīng)用的最佳配置费尽。
promotion failed:
垃圾回收時(shí)promotion failed是個(gè)很頭痛的問題赠群,一般可能是兩種原因產(chǎn)生:
- 第一個(gè)原因是救助空間不夠,救助空間里的對(duì)象還不應(yīng)該被移動(dòng)到年老代旱幼,但年輕代又有很多對(duì)象需要放入救助空間查描;
- 第二個(gè)原因是年老代沒有足夠的空間接納來自年輕代的對(duì)象;這兩種情況都會(huì)轉(zhuǎn)向Full GC柏卤,網(wǎng)站停頓時(shí)間較長冬三。
解決方方案一:
第一個(gè)原因我的最終解決辦法是去掉救助空間,設(shè)置
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
即可缘缚。
第二個(gè)原因我的解決辦法是設(shè)置CMSInitiatingOccupancyFraction為某個(gè)值(假設(shè)70)勾笆,這樣年老代空間到70%時(shí)就開始執(zhí)行CMS,年老代有足夠的空間接納來自年輕代的對(duì)象桥滨。
解決方案一的改進(jìn)方案:
又有改進(jìn)了窝爪,上面方法不太好,因?yàn)闆]有用到救助空間齐媒,所以年老代容易滿蒲每,CMS執(zhí)行會(huì)比較頻繁。我改善了一下喻括,還是用救助空間邀杏,但是把救助空間加大,這樣也不會(huì)有promotion failed唬血。具體操作上望蜡,32位Linux和64位Linux好像不一樣,64位系統(tǒng)似乎只要配置MaxTenuringThreshold參數(shù)刁品,CMS還是有暫停。為了解決暫停問題和promotion failed問題浩姥,最后我設(shè)置-XX:SurvivorRatio=1 挑随,并把MaxTenuringThreshold去掉,這樣即沒有暫停又不會(huì)有promotoin failed勒叠,而且更重要的是兜挨,年老代和永久代上升非常慢(因?yàn)楹枚鄬?duì)象到不了年老代就被回收了),所以CMS執(zhí)行頻率非常低眯分,好幾個(gè)小時(shí)才執(zhí)行一次拌汇,這樣,服務(wù)器都不用重啟了弊决。
-Xmx 4000M
-Xms 4000M
-Xmn 600M 年輕代大小
-XX:PermSize=500M 永久代初始值大小
-XX:MaxPermSize=500M 永久代最大值
-Xss 256K 線程大小
-XX:+DisableExplicitGC 關(guān)閉system.gc
-XX:SurvivorRatio=1 年輕代比值
-XX:+UseConcMarkSweepGC 使用CMS內(nèi)存收集
-XX:+UseParNewGC 設(shè)置年輕代使用并行收集
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection 老年代壓縮
-XX:CMSFullGCsBeforeCompaction=0 每次進(jìn)行壓縮
-XX:+CMSClassUnloadingEnabled
-XX:LargePageSizeInBytes=128M
-XX:+UseFastAccessorMethods 原始類型快速優(yōu)化
-XX:+UseCMSInitiatingOccupancyOnly 手動(dòng)觸發(fā)
-XX:CMSInitiatingOccupancyFraction=80 80%開始回收
-XX:SoftRefLRUPolicyMSPerMB=0 軟應(yīng)用存活時(shí)間
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
CMSInitiatingOccupancyFraction值與Xmn的關(guān)系公式
上面介紹了promontion faild產(chǎn)生的原因是EDEN空間不足的情況下將EDEN與From survivor中的存活對(duì)象存入To survivor區(qū)時(shí)噪舀,To survivor區(qū)的空間不足魁淳,再次晉升到old gen區(qū),而old gen區(qū)內(nèi)存也不夠的情況下產(chǎn)生了promontion faild從而導(dǎo)致full gc与倡。那可以推斷出:eden+from survivor < old gen區(qū)剩余內(nèi)存時(shí)界逛,不會(huì)出現(xiàn)promontion faild的情況,即:
(Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)>=(Xmn-Xmn/(SurvivorRatior+2))
進(jìn)而推斷出:
CMSInitiatingOccupancyFraction <=((Xmx-Xmn)-(Xmn-Xmn/(SurvivorRatior+2)))/(Xmx-Xmn)*100
例如:
當(dāng)xmx=128 xmn=36 SurvivorRatior=1時(shí) CMSInitiatingOccupancyFraction<=((128.0-36)-(36-36/(1+2)))/(128-36)*100 =73.913
當(dāng)xmx=128 xmn=24 SurvivorRatior=1時(shí) CMSInitiatingOccupancyFraction<=((128.0-24)-(24-24/(1+2)))/(128-24)*100=84.615…
當(dāng)xmx=3000 xmn=600 SurvivorRatior=1時(shí) CMSInitiatingOccupancyFraction<=((3000.0-600)-(600-600/(1+2)))/(3000-600)*100=83.33
CMSInitiatingOccupancyFraction低于70% 需要調(diào)整xmn或SurvivorRatior值纺座。
令:
網(wǎng)上一童鞋推斷出的公式是::(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn 這個(gè)公式個(gè)人認(rèn)為不是很嚴(yán)謹(jǐn)息拜,在內(nèi)存小的時(shí)候會(huì)影響xmn的計(jì)算。
實(shí)例:
- java application項(xiàng)目(非web)
改進(jìn)前:
-Xms128m
-Xmx128m
-XX:NewSize=64m
-XX:PermSize=64m
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=78
-XX:ThreadStackSize=128
-Xloggc:logs/gc.log
-Dsun.rmi.dgc.server.gcInterval=3600000
-Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.server.exceptionTrace=true
問題:
permsize 設(shè)置較小净响,很容易達(dá)到報(bào)警范圍(0.8)
沒有設(shè)置MaxPermSize少欺,堆增長會(huì)帶來額外壓力片排。
NewSize較大登下,old gen 剩余空間64m笋婿,一方面可能會(huì)帶來old區(qū)容易增長到報(bào)警范圍(監(jiān)控?cái)?shù)據(jù)顯示oldgenused長期在50m左右滋尉,接近78%家卖,容易出現(xiàn) full gc)潮剪,另一方面也存在 promontion fail 風(fēng)險(xiǎn)
改進(jìn)后:
-Xms128m
-Xmx128m
-Xmn24m
-XX:PermSize=80m
-XX:MaxPermSize=80m
-Xss256k
-XX:SurvivorRatio=1
-XX:MaxTenuringThreshold=20
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSParallelRemarkEnabled
-XX:CMSFullGCsBeforeCompaction=2
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:logs/gc.log
-Dsun.rmi.dgc.server.gcInterval=3600000
-Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.server.exceptionTrace=true
修改點(diǎn):
PermSize與MaxPermSize都設(shè)置為80裁良,一方面避免non heap warn(報(bào)警閥值0.8 非對(duì)內(nèi)存一般占用到60M以內(nèi))衷恭,一方面避免堆伸縮帶來的壓力
通過設(shè)置Xmn=24M及SurvivorRatio=1 使得Eden區(qū)=from space=to space=8M,降低了Eden區(qū)大小扰付,降低YGC的時(shí)間(降低到3-4ms左右)堤撵,同時(shí)通過設(shè)MaxTenuringThreshold=20,使得old gen的增長很緩慢羽莺。帶來的問題是YGC的次數(shù)明顯提高了很多实昨。
再次改進(jìn)后
-Xms128m
-Xmx128m
-Xmn36m
-XX:PermSize=80m
-XX:MaxPermSize=80m
-Xss256k
-XX:SurvivorRatio=1
-XX:MaxTenuringThreshold=20
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=73
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSParallelRemarkEnabled
-XX:CMSFullGCsBeforeCompaction=2
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:logs/gc.log
-Dsun.rmi.dgc.server.gcInterval=3600000
-Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.server.exceptionTrace=true
修改點(diǎn):
在上面的基礎(chǔ)上調(diào)整Xmn大小到36M,設(shè)置CMSInitiatingOccupancyFraction=73盐固。
Dden區(qū)與Survivor區(qū)大小都增加到12M荒给,通過下文的CMSInitiatingOccupancyFraction計(jì)算得出value為73是可以避免promotion faild問題,同時(shí)滿足堆內(nèi)存監(jiān)控報(bào)警值在80%:內(nèi)存大小128M80%=102.4M 102.4M-36M=66.4M(老年代達(dá)到此值報(bào)警) 老年代達(dá)到67.15M(92M0.73)將發(fā)生Full GC刁卜,所以在老生代大小達(dá)到66.4M時(shí)也就是WARN報(bào)警時(shí)將很有可能出現(xiàn)Full GC志电。增大了Eden和Survivor區(qū)的值,會(huì)減小YGC的次數(shù)蛔趴,但由于空間變大理論上也會(huì)相應(yīng)的增加YGC的時(shí)間挑辆,不過由于新生代本身就很小(才36M)這點(diǎn)兒變化可以忽略掉孝情。實(shí)際的監(jiān)控值顯示YGC的時(shí)間在4-5ms之間鱼蝉。是可以接受范圍。
SurvivorRatio 這個(gè)值還得在仔細(xì)考慮下,有待優(yōu)化中
網(wǎng)上某個(gè)牛人的配置 :每天幾百萬pv一點(diǎn)問題都沒有箫荡,網(wǎng)站沒有停頓
-server
-Xms6000M
-Xmx6000M
-Xmn500M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
說明一下魁亦,
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
就是去掉了救助空間;
-Xnoclassgc禁用類垃圾回收羔挡,性能會(huì)高一點(diǎn)洁奈;
-XX:+DisableExplicitGC禁止System.gc()间唉,免得程序員誤調(diào)用gc方法影響性能;
-XX:+UseParNewGC睬魂,對(duì)年輕代采用多線程并行回收终吼,這樣收得快;
帶CMS參數(shù)的都是和并發(fā)回收相關(guān)的际跪,不明白的可以上網(wǎng)搜索姆打;
SoftRefLRUPolicyMSPerMB這個(gè)參數(shù)我認(rèn)為可能有點(diǎn)用幔戏,官方解釋是softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap闲延,我覺得沒必要等1秒垒玲;
-Xmx4000M
-Xms4000M
-Xmn600M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-Xss256K
-XX:+DisableExplicitGC
-XX:SurvivorRatio=1
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:LargePageSizeInBytes=128M
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
改進(jìn)方案:
上面方法不太好合愈,因?yàn)闆]有用到救助空間,所以年老代容易滿寸莫,CMS執(zhí)行會(huì)比較頻繁档冬。我改善了一下辽狈,還是用救助空間呛牲,但是把救助空間加大娘扩,這樣也不會(huì)有promotion failed涮阔。
具體操作上灰殴,32位Linux和64位Linux好像不一樣伟阔,64位系統(tǒng)似乎只要配置MaxTenuringThreshold參數(shù)皱炉,CMS還是有暫停合搅。為了解決暫停問題和promotion failed問題灾部,最后我設(shè)置-XX:SurvivorRatio=1 梳猪,并把MaxTenuringThreshold去掉春弥,這樣即沒有暫停又不會(huì)有promotoin failed匿沛,而且更重要的是逃呼,年老代和永久代上升非常慢(因?yàn)楹枚鄬?duì)象到不了年老代就被回收了)抡笼,所以CMS執(zhí)行頻率非常低推姻,好幾個(gè)小時(shí)才執(zhí)行一次藏古,這樣拧晕,服務(wù)器都不用重啟了输玷。
某網(wǎng)友:
-server
-Xmx3000M
-Xms3000M
-Xmn600M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-Xss256K
-XX:+DisableExplicitGC
-XX:SurvivorRatio=1
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:LargePageSizeInBytes=128M
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
64位jdk參考設(shè)置饲嗽,年老代漲得很慢,CMS執(zhí)行頻率變小裙犹,CMS沒有停滯袄膏,也不會(huì)有promotion failed問題沉馆,內(nèi)存回收得很干凈
參考:
JVM參數(shù)調(diào)優(yōu),無停滯實(shí)踐
JVM系列四:生產(chǎn)環(huán)境參數(shù)實(shí)例及分析【生產(chǎn)環(huán)境實(shí)例增加中】
JAVA HOTSPOT VM(http://www.helloying.com/blog/archives/164)
java jvm 參數(shù) -Xms -Xmx -Xmn -Xss 調(diào)優(yōu)總結(jié)
http://bbs.weblogicfans.net/archiver/tid-2835.html
Frequently Asked Questions About the Java HotSpot VM
Java性能調(diào)優(yōu)筆記(內(nèi)附測試?yán)?很有用)