轉自百度空間,原文鏈接失效,內容來自百度快照html
常見配置舉例 堆大小設置 JVM 中最大堆大小有三方面限制:相關操做系統的數據模型(32-bt仍是64-bit)限制;系統的可用虛擬內存限制;系統的可用物理內存限制.32位系統 下,通常限制在1.5G~2G;64爲操做系統對內存無限制.我在Windows Server 2003 系統,3.5G物理內存,JDK5.0下測試,最大可設置爲1478m. 典型設置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -Xmx3550m:設置JVM最大可用內存爲3550M. -Xms3550m:設置JVM促使內存爲3550m.此值能夠設置與-Xmx相同,以免每次垃圾回收完成後JVM從新分配內存. -Xmn2g:設置年輕代大小爲2G.整個堆大小=年輕代大小 + 年老代大小 + 持久代大小.持久代通常固定大小爲64m,因此增大年輕代後,將會減少年老代大小.此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8. -Xss128k: 設置每一個線程的堆棧大小.JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K.更具應用的線程所需內存大小進行 調整.在相同物理內存下,減少這個值能生成更多的線程.可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右. java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0 -XX:NewRatio=4:設置年輕代(包括Eden和兩個Survivor區)與年老代的比值(除去持久代).設置爲4,則年輕代與年老代所佔比值爲1:4,年輕代佔整個堆棧的1/5 -XX:SurvivorRatio=4:設置年輕代中Eden區與Survivor區的大小比值.設置爲4,則兩個Survivor區與一個Eden區的比值爲2:4,一個Survivor區佔整個年輕代的1/6 -XX:MaxPermSize=16m:設置持久代大小爲16m. -XX:MaxTenuringThreshold=0: 設置垃圾最大年齡.若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代. 對於年老代比較多的應用,能夠提升效率.若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活 時間,增長在年輕代即被回收的概論. 回收器選擇 JVM給了三種選擇:串行收集器,並行收集器,併發收集器,可是串行收集器只適用於小數據 量的狀況,因此這裏的選擇主要針對並行收集器和併發收集器.默認 狀況下,JDK5.0之前都是使用串行收集器,若是想使用其餘收集器須要在啓動時加入相應參數.JDK5.0之後,JVM會根據當前系統配置進行判斷. 吞吐量優先的並行收集器 如上文所述,並行收集器主要以到達必定的吞吐量爲目標,適用於科學技術和後臺處理等. 典型配置: java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelGC:選擇垃圾收集器爲並行收集器.此配置僅對年輕代有效.即上述配置下,年輕代使用併發收集,而年老代仍舊使用串行收集. -XX:ParallelGCThreads=20:配置並行收集器的線程數,即:同時多少個線程一塊兒進行垃圾回收.此值最好配置與處理器數目相等. java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:+UseParallelOldGC:配置年老代垃圾收集方式爲並行收集.JDK6.0支持對年老代並行收集. java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:MaxGCPauseMillis=100:設置每次年輕代垃圾回收的最長時間,若是沒法知足此時間,JVM會自動調全年輕代大小,以知足此值. java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy -XX:+UseAdaptiveSizePolicy:設置此選項後,並行收集器會自動選擇年輕代區大小和相應的Survivor區比例,以達到目標系統規定的最低相應時間或者收集頻率等,此值建議使用並行收集器時,一直打開. 響應時間優先的併發收集器 如上文所述,併發收集器主要是保證系統的響應時間,減小垃圾收集時的停頓時間.適用於應用服務器,電信領域等. 典型配置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC:設置年老代爲併發收集.測試中配置這個之後,-XX:NewRatio=4的配置失效了,緣由不明.因此,此時年輕代大小最好用-Xmn設置. -XX:+UseParNewGC:設置年輕代爲並行收集.可與CMS收集同時使用.JDK5.0以上,JVM會根據系統配置自行設置,因此無需再設置此值. java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction:因爲併發收集器不對內存空間進行壓縮,整理,因此運行一段時間之後會產生"碎片",使得運行效率下降.此值設置運行多少次GC之後對內存空間進行壓縮,整理. -XX:+UseCMSCompactAtFullCollection:打開對年老代的壓縮.可能會影響性能,可是能夠消除碎片 輔助信息 JVM提供了大量命令行參數,打印信息,供調試使用.主要有如下一些: -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可與上面兩個混合使用 輸出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs] -XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中斷的執行時間.可與上面混合使用 輸出形式:Application time: 0.5291524 seconds -XX:+PrintGCApplicationStoppedTime:打印垃圾回收期間程序暫停的時間.可與上面混合使用 輸出形式:Total time for which application threads were stopped: 0.0468229 seconds -XX:PrintHeapAtGC:打印GC先後的詳細堆棧信息 輸出形式: 34.702: [GC {Heap before gc invocations=7: def new generation total 55296K, used 52568K [0x1ebd0000, 0x227d0000, 0x227d0000) eden space 49152K, 99% used [0x1ebd0000, 0x21bce430, 0x21bd0000) from space 6144K, 55% used [0x221d0000, 0x22527e10, 0x227d0000) to space 6144K, 0% used [0x21bd0000, 0x21bd0000, 0x221d0000) tenured generation total 69632K, used 2696K [0x227d0000, 0x26bd0000, 0x26bd0000) the space 69632K, 3% used [0x227d0000, 0x22a720f8, 0x22a72200, 0x26bd0000) compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000) the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000) ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000) rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000) 34.735: [DefNew: 52568K->3433K(55296K), 0.0072126 secs] 55264K->6615K(124928K)Heap after gc invocations=8: def new generation total 55296K, used 3433K [0x1ebd0000, 0x227d0000, 0x227d0000) eden space 49152K, 0% used [0x1ebd0000, 0x1ebd0000, 0x21bd0000) from space 6144K, 55% used [0x21bd0000, 0x21f2a5e8, 0x221d0000) to space 6144K, 0% used [0x221d0000, 0x221d0000, 0x227d0000) tenured generation total 69632K, used 3182K [0x227d0000, 0x26bd0000, 0x26bd0000) the space 69632K, 4% used [0x227d0000, 0x22aeb958, 0x22aeba00, 0x26bd0000) compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000) the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000) ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000) rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000) } , 0.0757599 secs] -Xloggc:filename:與上面幾個配合使用,把相關日誌信息記錄到文件以便分析. 常見配置彙總 堆設置 -Xms:初始堆大小 -Xmx:最大堆大小 -XX:NewSize=n:設置年輕代大小 -XX:NewRatio=n:設置年輕代和年老代的比值.如:爲3,表示年輕代與年老代比值爲1:3,年輕代佔整個年輕代年老代和的1/4 -XX:SurvivorRatio=n:年輕代中Eden區與兩個Survivor區的比值.注意Survivor區有兩個.如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個年輕代的1/5 -XX:MaxPermSize=n:設置持久代大小 收集器設置 -XX:+UseSerialGC:設置串行收集器 -XX:+UseParallelGC:設置並行收集器 -XX:+UseParalledlOldGC:設置並行年老代收集器 -XX:+UseConcMarkSweepGC:設置併發收集器 垃圾回收統計信息 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:filename 並行收集器設置 -XX:ParallelGCThreads=n:設置並行收集器收集時使用的CPU數.並行收集線程數. -XX:MaxGCPauseMillis=n:設置並行收集最大暫停時間 -XX:GCTimeRatio=n:設置垃圾回收時間佔程序運行時間的百分比.公式爲1/(1+n) 併發收集器設置 -XX:+CMSIncrementalMode:設置爲增量模式.適用於單CPU狀況. -XX:ParallelGCThreads=n:設置併發收集器年輕代收集方式爲並行收集時,使用的CPU數.並行收集線程數. 調優總結 年輕代大小選擇 響應時間優先的應用:儘量設大,直到接近系統的最低響應時間限制(根據實際狀況選擇).在此種狀況下,年輕代收集發生的頻率也是最小的.同時,減小到達年老代的對象. 吞吐量優先的應用:儘量的設置大,可能到達Gbit的程度.由於對響應時間沒有要求,垃圾收集能夠並行進行,通常適合8CPU以上的應用. 年老代大小選擇 響 應時間優先的應用:年老代使用併發收集器,因此其大小須要當心設置,通常要考慮併發會話率和會話持續時間等一些參數.若是堆設置小了,能夠會形成內存碎 片,高回收頻率以及應用暫停而使用傳統的標記清除方式;若是堆大了,則須要較長的收集時間.最優化的方案,通常須要參考如下數據得到: 併發垃圾收集信息 持久代併發收集次數 傳統GC信息 花在年輕代和年老代回收上的時間比例 減小年輕代和年老代花費的時間,通常會提升應用的效率 吞吐量優先的應用:通常吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代.緣由是,這樣能夠儘量回收掉大部分短時間對象,減小中期的對象,而年老代盡存放長期存活對象. 較小堆引發的碎片問題 因 爲年老代的併發收集器使用標記,清除算法,因此不會對堆進行壓縮.當收集器回收時,他會把相鄰的空間進行合併,這樣能夠分配給較大的對象.可是,當堆空 間較小時,運行一段時間之後,就會出現"碎片",若是併發收集器找不到足夠的空間,那麼併發收集器將會中止,而後使用傳統的標記,清除方式進行回收.若是 出現"碎片",可能須要進行以下配置: -XX:+UseCMSCompactAtFullCollection:使用併發收集器時,開啓對年老代的壓縮. -XX:CMSFullGCsBeforeCompaction=0:上面配置開啓的狀況下,這裏設置多少次Full GC後,對年老代進行壓縮 在 同一個工程下,有兩個類,這兩個類中只有不多的變更,而最關健的FOR卻沒有一點變更,但是當我分別運行這兩個程序的時候卻出現一個很嚴重的問題,一個程 序循環的快,一個循環的慢.這究竟是怎麼回事呢~???苦苦尋找了半天也沒有想到是爲何,由於程序改變的部分根不影響我循環的速度,但是結果倒是有很大 的差異,一個大約是在一分鐘這內就能夠循環完,但是另外一個卻須要六七分鐘,這根本就不是一個數據理級的麻.兩個徹底同樣的循環,從代碼上根本上是看不出有 什麼問題.不得以求助同事吧,但是同事看了也感受很詭異,兩我的在那訂着代碼又看了一個多小時,最後同事讓我來個乾淨點的,關機重啓.我到也聽話,就順着 同事的意思去了,可就在關機的這個時候他忽然說是否是內存的問題,我也空然想到了,還真的有多是內存的問題,由於快的那個在我以前運行程序以前可給過 1G的內存啊,然後來的這個我好像是沒有設過內存啊,機器起來了,有了這個想法進去看看吧,結果正中要害,果然是慢的那個沒有開內存,程序運行時只不過是 JVM默認開的內存.我初步分析是由於內存過小,而個人程序所用內存又正好卡在JVM所開內存邊上,不至於溢出.當程序運行時就得花費大部分時間去調用 GC去,這樣就致使了爲何相同的循環出現兩種不一樣的效率~! 順便把內存使用狀況的方法也貼出來: public static String getMemUsage() { long free = java.lang.Runtime.getRuntime().freeMemory(); long total = java.lang.Runtime.getRuntime().totalMemory();
StringBuffer buf = new StringBuffer(); buf.append("[Mem: used ").append((total-free)>>20) .append("M free ").append(free>>20) .append("M total ").append(total>>20).append("M]"); return buf.toString(); } google一下,大概就說JVM是這樣來操做內存: 堆(Heap)和非堆(Non-heap)內存 按 照官方的說法:"Java 虛擬機具備一個堆,堆是運行時數據區域,全部類實例和數組的內存均今後處分配.堆是在 Java 虛擬機啓動時建立的.""在JVM中堆以外的內存稱爲非堆內存(Non-heap memory)".能夠看出JVM主要管理兩種類型的內存:堆和非堆.簡單來講堆就是Java代碼可及的內存,是留給開發人員使用的;非堆就是JVM留給 本身用的,因此方法區,JVM內部處理或優化所需的內存(如JIT編譯後的代碼緩存),每一個類結構(如運行時常數池,字段和方法數據)以及方法和構造方法 的代碼都在非堆內存中. 堆內存分配 JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的內存由-Xmx指 定,默認是物理內存的1/4.默認空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆內存大於70%時, JVM會減小堆直到-Xms的最小限制.所以服務器通常設置-Xms,-Xmx相等以免在每次GC 後調整堆的大小. 非堆內存分配 JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4. JVM內存限制(最大值) 首 先JVM內存首先受限於實際的最大物理內存,假設物理內存無限大的話,JVM內存的最大值跟操做系統有很大的關係.簡單的說就32位處理器雖然可控內存空 間有4GB,可是具體的操做系統會給一個限制,這個限制通常是 2GB-3GB(通常來講Windows系統下爲1.5G-2G,Linux系統下爲2G-3G),而64bit以上的處理器就不會有限制了 JVM內存的調優java
######################### ####如下內容轉自http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html ######################################web
無論是YGC仍是Full GC,GC過程當中都會對致使程序運行中中斷,正確的選擇不一樣的GC策略,調整JVM、GC的參數,能夠極大的減小因爲GC工做,而致使的程序運行中斷方面的問題,進而適當的提升Java程序的工做效率。可是調整GC是以個極爲複雜的過程,因爲各個程序具有不一樣的特色,如:web和GUI程序就有很大區別(Web能夠適當的停頓,但GUI停頓是客戶沒法接受的),並且因爲跑在各個機器上的配置不一樣(主要cup個數,內存不一樣),因此使用的GC種類也會不一樣(如何選擇見GC種類及如何選擇)。本文將注重介紹JVM、GC的一些重要參數的設置來提升系統的性能。算法
JVM內存組成及GC相關內容請見以前的文章:JVM內存組成 GC策略&內存申請。
JVM參數的含義 實例見實例分析數組
參數名稱 含義 默認值
-Xms 初始堆大小 物理內存的1/64(<1GB) 默認(MinHeapFreeRatio參數能夠調整)空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制. -Xmx 最大堆大小 物理內存的1/4(<1GB) 默認(MaxHeapFreeRatio參數能夠調整)空餘堆內存大於70%時,JVM會減小堆直到 -Xms的最小限制 -Xmn 年輕代大小(1.4or lator) 注意:此處的大小是(eden+ 2 survivor space).與jmap -heap中顯示的New gen是不一樣的。 整個堆大小=年輕代大小 + 年老代大小 + 持久代大小. 增大年輕代後,將會減少年老代大小.此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8 -XX:NewSize 設置年輕代大小(for 1.3/1.4)
-XX:MaxNewSize 年輕代最大值(for 1.3/1.4)
-XX:PermSize 設置持久代(perm gen)初始值 物理內存的1/64
-XX:MaxPermSize 設置持久代最大值 物理內存的1/4
-Xss 每一個線程的堆棧大小 JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K.更具應用的線程所需內存大小進行 調整.在相同物理內存下,減少這個值能生成更多的線程.可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右 通常小的應用, 若是棧不是很深, 應該是128k夠用的 大的應用建議使用256k。這個選項對性能影響比較大,須要嚴格的測試。(校長) 和threadstacksize選項解釋很相似,官方文檔彷佛沒有解釋,在論壇中有這樣一句話:"」 -Xss is translated in a VM flag named ThreadStackSize」 通常設置這個值就能夠了。 -XX:ThreadStackSize Thread Stack Size (0 means use default 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和兩個Survivor區)與年老代的比值(除去持久代) -XX:NewRatio=4表示年輕代與年老代所佔比值爲1:4,年輕代佔整個堆棧的1/5 Xms=Xmx而且設置了Xmn的狀況下,該參數不須要進行設置。 -XX:SurvivorRatio Eden區與Survivor區的大小比值 設置爲8,則兩個Survivor區與一個Eden區的比值爲2:8,一個Survivor區佔整個年輕代的1/10 -XX:LargePageSizeInBytes 內存頁的大小不可設置過大, 會影響Perm的大小 =128m -XX:+UseFastAccessorMethods 原始類型的快速優化
-XX:+DisableExplicitGC 關閉System.gc() 這個參數須要嚴格的測試 -XX:MaxTenuringThreshold 垃圾最大年齡 若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代. 對於年老代比較多的應用,能夠提升效率.若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活 時間,增長在年輕代即被回收的機率 該參數只有在串行GC時纔有效. -XX:+AggressiveOpts 加快編譯
-XX:+UseBiasedLocking 鎖機制的性能改善
-Xnoclassgc 禁用垃圾回收
-XX:SoftRefLRUPolicyMSPerMB 每兆堆空閒空間中SoftReference的存活時間 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 對象超過多大是直接在舊生代分配 0 單位字節 新生代採用Parallel Scavenge GC時無效 另外一種直接在舊生代分配的狀況是大的數組對象,且數組中無外部引用對象. -XX:TLABWasteTargetPercent TLAB佔eden區的百分比 1%
-XX:+CollectGen0First FullGC時是否先YGC false
並行收集器相關參數緩存
-XX:+UseParallelGC Full GC採用parallel MSC (此項待驗證) 選擇垃圾收集器爲並行收集器.此配置僅對年輕代有效.即上述配置下,年輕代使用併發收集,而年老代仍舊使用串行收集.(此項待驗證)服務器
-XX:+UseParNewGC 設置年輕代爲並行收集 可與CMS收集同時使用 JDK5.0以上,JVM會根據系統配置自行設置,因此無需再設置此值 -XX:ParallelGCThreads 並行收集器的線程數 此值最好配置與處理器數目相等 一樣適用於CMS -XX:+UseParallelOldGC 年老代垃圾收集方式爲並行收集(Parallel Compacting) 這個是JAVA 6出現的參數選項 -XX:MaxGCPauseMillis 每次年輕代垃圾回收的最長時間(最大暫停時間) 若是沒法知足此時間,JVM會自動調全年輕代大小,以知足此值. -XX:+UseAdaptiveSizePolicy 自動選擇年輕代區大小和相應的Survivor區比例 設置此選項後,並行收集器會自動選擇年輕代區大小和相應的Survivor區比例,以達到目標系統規定的最低相應時間或者收集頻率等,此值建議使用並行收集器時,一直打開. -XX:GCTimeRatio 設置垃圾回收時間佔程序運行時間的百分比 公式爲1/(1+n) -XX:+ScavengeBeforeFullGC Full GC前調用YGC true Do young generation GC prior to a full GC. (Introduced in 1.4.1.) CMS相關參數多線程
-XX:+UseConcMarkSweepGC 使用CMS內存收集 測試中配置這個之後,-XX:NewRatio=4的配置失效了,緣由不明.因此,此時年輕代大小最好用-Xmn設置.??? -XX:+AggressiveHeap 試圖是使用大量的物理內存 長時間大內存使用的優化,能檢查計算資源(內存, 處理器數量) 至少須要256MB內存 大量的CPU/內存, (在1.4.1在4CPU的機器上已經顯示有提高) -XX:CMSFullGCsBeforeCompaction 多少次後進行內存壓縮 因爲併發收集器不對內存空間進行壓縮,整理,因此運行一段時間之後會產生"碎片",使得運行效率下降.此值設置運行多少次GC之後對內存空間進行壓縮,整理. -XX:+CMSParallelRemarkEnabled 下降標記停頓
-XX+UseCMSCompactAtFullCollection 在FULL GC的時候, 對年老代的壓縮 CMS是不會移動內存的, 所以, 這個很是容易產生碎片, 致使內存不夠用, 所以, 內存的壓縮這個時候就會被啓用。 增長這個參數是個好習慣。 可能會影響性能,可是能夠消除碎片 -XX:+UseCMSInitiatingOccupancyOnly 使用手動定義初始化定義開始CMS收集 禁止hostspot自行觸發CMS GC -XX:CMSInitiatingOccupancyFraction=70 使用cms做爲垃圾回收 使用70%後開始CMS收集 92 爲了保證不出現promotion failed(見下面介紹)錯誤,該值的設置須要知足如下公式CMSInitiatingOccupancyFraction計算公式 -XX:CMSInitiatingPermOccupancyFraction 設置Perm Gen使用到達多少比率時觸發 92
-XX:+CMSIncrementalMode 設置爲增量模式 用於單CPU狀況 -XX:+CMSClassUnloadingEnabled
輔助信息併發
-XX:+PrintGC 輸出形式:app
[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 打印垃圾回收期間程序暫停的時間.可與上面混合使用 輸出形式:Total time for which application threads were stopped: 0.0468229 seconds -XX:+PrintGCApplicationConcurrentTime 打印每次垃圾回收前,程序未中斷的執行時間.可與上面混合使用 輸出形式:Application time: 0.5291524 seconds -XX:+PrintHeapAtGC 打印GC先後的詳細堆棧信息
-Xloggc:filename 把相關日誌信息記錄到文件以便分析. 與上面幾個配合使用
-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即標識新的存活週期的閾值爲7。
GC性能方面的考慮
對於GC的性能主要有2個方面的指標:吞吐量throughput(工做時間不算gc的時間佔總的時間比)和暫停pause(gc發生時app對外顯示的沒法響應)。
Total Heap
默認狀況下,vm會增長/減小heap大小以維持free space在整個vm中佔的比例,這個比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。
通常而言,server端的app會有如下規則:
對vm分配儘量多的memory; 將Xms和Xmx設爲同樣的值。若是虛擬機啓動時設置使用的內存比較小,這個時候又須要初始化不少對象,虛擬機就必須重複地增長內存。 處理器核數增長,內存也跟着增大。 2. The Young Generation
另一個對於app流暢性運行影響的因素是young generation的大小。young generation越大,minor collection越少;可是在固定heap size狀況下,更大的young generation就意味着小的tenured generation,就意味着更多的major collection(major collection會引起minor collection)。 NewRatio反映的是young和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,將這兩個值設爲同樣就固定了young generation的大小(同Xms和Xmx設爲同樣)。 若是但願,SurvivorRatio也能夠優化survivor的大小,不過這對於性能的影響不是很大。SurvivorRatio是eden和survior大小比例。
通常而言,server端的app會有如下規則:
首先決定能分配給vm的最大的heap size,而後設定最佳的young generation的大小; 若是heap size固定後,增長young generation的大小意味着減少tenured generation大小。讓tenured generation在任什麼時候候夠大,可以容納全部live的data(留10%-20%的空餘)。 經驗&&規則
年輕代大小選擇 響應時間優先的應用:儘量設大,直到接近系統的最低響應時間限制(根據實際狀況選擇).在此種狀況下,年輕代收集發生的頻率也是最小的.同時,減小到達年老代的對象. 吞吐量優先的應用:儘量的設置大,可能到達Gbit的程度.由於對響應時間沒有要求,垃圾收集能夠並行進行,通常適合8CPU以上的應用. 避免設置太小.當新生代設置太小時會致使:1.YGC次數更加頻繁 2.可能致使YGC對象直接進入舊生代,若是此時舊生代滿了,會觸發FGC. 年老代大小選擇 響應時間優先的應用:年老代使用併發收集器,因此其大小須要當心設置,通常要考慮併發會話率和會話持續時間等一些參數.若是堆設置小了,能夠會形成內存碎 片,高回收頻率以及應用暫停而使用傳統的標記清除方式;若是堆大了,則須要較長的收集時間.最優化的方案,通常須要參考如下數據得到: 併發垃圾收集信息、持久代併發收集次數、傳統GC信息、花在年輕代和年老代回收上的時間比例。 吞吐量優先的應用:通常吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代.緣由是,這樣能夠儘量回收掉大部分短時間對象,減小中期的對象,而年老代盡存放長期存活對象. 較小堆引發的碎片問題 由於年老代的併發收集器使用標記,清除算法,因此不會對堆進行壓縮.當收集器回收時,他會把相鄰的空間進行合併,這樣能夠分配給較大的對象.可是,當堆空間較小時,運行一段時間之後,就會出現"碎片",若是併發收集器找不到足夠的空間,那麼併發收集器將會中止,而後使用傳統的標記,清除方式進行回收.若是出現"碎片",可能須要進行以下配置: -XX:+UseCMSCompactAtFullCollection:使用併發收集器時,開啓對年老代的壓縮. -XX:CMSFullGCsBeforeCompaction=0:上面配置開啓的狀況下,這裏設置多少次Full GC後,對年老代進行壓縮 用64位操做系統,Linux下64位的jdk比32位jdk要慢一些,可是吃得內存更多,吞吐量更大 XMX和XMS設置同樣大,MaxPermSize和MinPermSize設置同樣大,這樣能夠減輕伸縮堆大小帶來的壓力 使用CMS的好處是用盡可能少的新生代,經驗值是128M-256M, 而後老生代利用CMS並行收集, 這樣能保證系統低延遲的吞吐效率。 實際上cms的收集停頓時間很是的短,2G的內存, 大約20-80ms的應用程序停頓時間 系統停頓的時候多是GC的問題也多是程序的問題,多用jmap和jstack查看,或者killall -3 java,而後查看java控制檯日誌,能看出不少問題。(相關工具的使用方法將在後面的blog中介紹) 仔細瞭解本身的應用,若是用了緩存,那麼年老代應該大一些,緩存的HashMap不該該無限制長,建議採用LRU算法的Map作緩存,LRUMap的最大長度也要根據實際狀況設定。 採用併發回收時,年輕代小一點,年老代要大,由於年老大用的是併發回收,即便時間長點也不會影響其餘程序繼續運行,網站不會停頓 JVM參數的設置(特別是 –Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等參數的設置沒有一個固定的公式,須要根據PV old區實際數據 YGC次數等多方面來衡量。爲了不promotion faild可能會致使xmn設置偏小,也意味着YGC的次數會增多,處理併發訪問的能力降低等問題。每一個參數的調整都須要通過詳細的性能測試,才能找到特定應用的最佳配置。 promotion failed:
垃圾回收時promotion failed是個很頭痛的問題,通常多是兩種緣由產生,第一個緣由是救助空間不夠,救助空間裏的對象還不該該被移動到年老代,但年輕代又有不少對象須要放入救助空間;第二個緣由是年老代沒有足夠的空間接納來自年輕代的對象;這兩種狀況都會轉向Full GC,網站停頓時間較長。
解決方方案一:
第一個緣由個人最終解決辦法是去掉救助空間,設置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0便可,第二個緣由個人解決辦法是設置CMSInitiatingOccupancyFraction爲某個值(假設70),這樣年老代空間到70%時就開始執行CMS,年老代有足夠的空間接納來自年輕代的對象。
解決方案一的改進方案:
又有改進了,上面方法不太好,由於沒有用到救助空間,因此年老代容易滿,CMS執行會比較頻繁。我改善了一下,仍是用救助空間,可是把救助空間加大,這樣也不會有promotion failed。具體操做上,32位Linux和64位Linux好像不同,64位系統彷佛只要配置MaxTenuringThreshold參數,CMS仍是有暫停。爲了解決暫停問題和promotion failed問題,最後我設置-XX:SurvivorRatio=1 ,並把MaxTenuringThreshold去掉,這樣即沒有暫停又不會有promotoin failed,並且更重要的是,年老代和永久代上升很是慢(由於好多對象到不了年老代就被回收了),因此CMS執行頻率很是低,好幾個小時才執行一次,這樣,服務器都不用重啓了。
-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
CMSInitiatingOccupancyFraction值與Xmn的關係公式
上面介紹了promontion faild產生的緣由是EDEN空間不足的狀況下將EDEN與From survivor中的存活對象存入To survivor區時,To survivor區的空間不足,再次晉升到old gen區,而old gen區內存也不夠的狀況下產生了promontion faild從而致使full gc.那能夠推斷出:eden+from survivor < old gen區剩餘內存時,不會出現promontion faild的狀況,即: (Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)>=(Xmn-Xmn/(SurvivorRatior+2)) 進而推斷出:
CMSInitiatingOccupancyFraction <=((Xmx-Xmn)-(Xmn-Xmn/(SurvivorRatior+2)))/(Xmx-Xmn)*100
例如:
當xmx=128 xmn=36 SurvivorRatior=1時 CMSInitiatingOccupancyFraction<=((128.0-36)-(36-36/(1+2)))/(128-36)*100 =73.913
當xmx=128 xmn=24 SurvivorRatior=1時 CMSInitiatingOccupancyFraction<=((128.0-24)-(24-24/(1+2)))/(128-24)*100=84.615…
當xmx=3000 xmn=600 SurvivorRatior=1時 CMSInitiatingOccupancyFraction<=((3000.0-600)-(600-600/(1+2)))/(3000-600)*100=83.33
CMSInitiatingOccupancyFraction低於70% 須要調整xmn或SurvivorRatior值。
令:
網上一童鞋推斷出的公式是::(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn 這個公式我的認爲不是很嚴謹,在內存小的時候會影響xmn的計算。
關於實際環境的GC參數配置見:實例分析 監測工具見JVM監測
參考:
JAVA HOTSPOT VM(http://www.helloying.com/blog/archives/164)
JVM 幾個重要的參數 (校長)
java jvm 參數 -Xms -Xmx -Xmn -Xss 調優總結
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性能調優筆記(內附測試例子 頗有用)
說說MaxTenuringThreshold這個參數
相關文章推薦:
GC調優方法總結
Java 6 JVM參數選項大全(中文版)