JVM調(diào)優(yōu)學(xué)習(xí)整理

  • 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è)比例 MinHeapFreeRatioMaxHeapFreeRatio指定趾徽。

一般而言续滋,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ī)則

  1. 年輕代大小選擇

    • 響應(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。
  2. 年老代大小選擇

    • 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系列三:JVM參數(shù)設(shè)置锌奴、分析

JVM系列四:生產(chǎn)環(huán)境參數(shù)實(shí)例及分析【生產(chǎn)環(huán)境實(shí)例增加中】

JAVA HOTSPOT VM(http://www.helloying.com/blog/archives/164

JVM 幾個(gè)重要的參數(shù)

java jvm 參數(shù) -Xms -Xmx -Xmn -Xss 調(diào)優(yōu)總結(jié)

Java HotSpot VM Options

http://bbs.weblogicfans.net/archiver/tid-2835.html

Frequently Asked Questions About the Java HotSpot VM

Java SE HotSpot at a Glance

Java性能調(diào)優(yōu)筆記(內(nèi)附測試?yán)?很有用)

說說MaxTenuringThreshold這個(gè)參數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市茴恰,隨后出現(xiàn)的幾起案子往枣,更是在濱河造成了極大的恐慌,老刑警劉巖丈秩,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異肠牲,居然都是意外死亡靴跛,警方通過查閱死者的電腦和手機(jī)肥印,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藏畅,“玉大人敷硅,你說我怎么就攤上這事∮溲郑” “怎么了绞蹦?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長榜旦。 經(jīng)常有香客問我坦辟,道長,這世上最難降的妖魔是什么章办? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上八秃,老公的妹妹穿的比我還像新娘骤肛。我一直安慰自己淑玫,他們只是感情好歌径,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布袭祟。 她就那樣靜靜地躺著胆绊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慨蛙,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音讽营,去河邊找鬼挑围。 笑死蜘矢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼绞佩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扑馁,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤酸些,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后檐蚜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體填帽,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宠进。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡藐翎,死狀恐怖材蹬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吝镣,我是刑警寧澤堤器,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站末贾,受9級(jí)特大地震影響闸溃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拱撵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一辉川、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拴测,春花似錦乓旗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汇跨。三九已至,卻和暖如春渺鹦,著一層夾襖步出監(jiān)牢的瞬間扰法,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工毅厚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塞颁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓吸耿,卻偏偏與公主長得像祠锣,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咽安,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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