1. 程式人生 > >JVM調優參數匯總

JVM調優參數匯總

oop csb gdi 時間戳 怎麽 note disable space 調試

一、JVM升級: ① Sun公司的HotSpot; ② BEA公司的JRockit; ③ IBM公司的J9 JVM; 在JDK1.7及其以前我們所使用的都是Sun公司的HotSpot,但由於Sun公司和BEA公司都被oracle收購,jdk1.8將采用Sun公司的HotSpot和BEA公司的JRockit兩個JVM中精華形成jdk1.8的JVM。 技術分享圖片 技術分享圖片   1.1對比:     JDK 1.7 及以往的 JDK 版本中,Java 類信息、常量池、靜態變量都存儲在 Perm(永久代)裏。類的元數據和靜態變量在類加載的時候分配到 Perm,當類被卸載的時候垃圾收集器從 Perm 處理掉類的元數據和靜態變量。當然常量池的東西也會在 Perm 垃圾收集的時候進行處理。     JDK 1.8 的對 JVM 架構的改造將類元數據放到本地內存中,另外,將常量池和靜態變量放到 Java 堆裏。HotSpot VM 將會為類的元數據明確分配和釋放本地內存。在這種架構下,類元信息就突破了原來 -XX:MaxPermSize 的限制,現在可以使用更多的本地內存。這樣就從一定程度上解決了原來在運行時生成大量類的造成經常 Full GC 問題,如運行時使用反射、代理等。   1.2註意:     如果服務器內存足夠,升級到 JDK 1.8 修改 JVM 參數最簡單的辦法就是將 -XX:PermSize 和 -XX:MaxPermSize 參數替換為 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize     1.8中-XX:PermSize 和 -XX:MaxPermSize 已經失效,取而代之的是一個新的區域 —— Metaspace(元數據區)。     使用JDK1.8以及之後的版本,不會再碰上“java.lang.OutOfMemoryError: PermGen space”這個錯誤了。   1.3優勢理解:     permSize:原來的jar包及你自己項目的class存放的內存空間,這部分空間是固定的,啟動參數裏面-permSize確定,如果你的jar包很多,經常會遇到permSize溢出,且每個項目都會占用自己的permGen空間     改成metaSpaces,各個項目會共享同樣的class內存空間,比如兩個項目都用了fast-json開源包,在mentaSpaces裏面只存一份class,提高內存利用率,且更利於垃圾回收    1.4區別     元空間並不在虛擬機中,而是使用本地內存。因此,默認情況下,元空間的大小僅受本地內存限制    1.5參數來指定元空間的大小        -XX:MetaspaceSize,初始空間大小,達到該值就會觸發垃圾收集進行類型卸載,同時GC會對該值進行調整:如果釋放了大量的空間,就適當降低該值;如果釋放了很少的空間,那麽在不超過MaxMetaspaceSize時,適當提高該值。     -XX:MaxMetaspaceSize,最大空間,默認是沒有限制的。     除了上面兩個指定大小的選項以外,還有兩個與 GC 相關的屬性:     -XX:MinMetaspaceFreeRatio,在GC之後,最小的Metaspace剩余空間容量的百分比,減少為分配空間所導致的垃圾收集     -XX:MaxMetaspaceFreeRatio,在GC之後,最大的Metaspace剩余空間容量的百分比,減少為釋放空間所導致的垃圾收集 二、 JVM啟動參數共分為三類:   1、標準參數(-),所有的JVM實現都必須實現這些參數的功能,而且向後兼容。例如:-verbose:class(輸出jvm載入類的相關信息,當jvm報告說找不到類或者類沖突時可此進行診斷);-verbose:gc(輸出每次GC的相關情況);-verbose:jni(輸出native方法調用的相關情況,一般用於診斷jni調用錯誤信息)。   2、非標準參數(-X),默認jvm實現這些參數的功能,但是並不保證所有jvm實現都滿足,且不保證向後兼容。例如:-Xms512m;-Xmx512m;-Xmn200m;-Xss128k)。   3、非Stable參數(-XX),此類參數各個jvm實現會有所不同,將來可能會隨時取消,需要慎重使用。例如:-XX:PermSize=64m;-XX:MaxPermSize=512m。 三、匯總 1、JVM-調優參數-JDK1.7 基本選項(選取部分)
-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的大小 因為每頁size變大了,導致JVM在計算Heap內部分區(perm, new, old)內存占用比例時,會出現超出正常值的劃分。最壞情況下是,某個區會多占用一個頁的大小。不過後續jvm版本也在調整這個策略。 一般情況,不建議將頁size調得太大,4-64M,是可以接受的(默認是4M)。 另外,網上有很多GC調優的文章內容中都有提到 LargePageSizeInBytes,但未提任何OS限制。在OS不支持的情況下,設置這個參數,這個參數將僅僅是個擺設。
-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: -DisableExplicitGC 默認情況下只要調用System.gc()就可以開啟.使用-XX:+DisableExplicitGC關閉調用System.gc(),==註意,當內存不足時,JVM依然會產生垃圾回收動作==
並行收集器相關參數
-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:+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 和上面的配合使用
-XX:CMSInitiatingPermOccupancyFraction 設置Perm Gen使用到達多少比率時觸發 92
-XX:+CMSIncrementalMode 設置為增量模式 用於單CPU情況
-XX:+CMSClassUnloadingEnabled
垃圾第一(G1),垃圾回收選項
選項和默認值 描述
-XX:+UseG1GC 使用垃圾優先(G1)回收器
-XX:MaxGCPauseMillis=n 設置回收器的最大停頓時間,這是一個比較簡單的目標,JVM將盡最大努力去實現它
-XX:InitiatingHeapOccupancyPercent=n 在並行GC模式下的堆占用率,它影響的是全部運行並行GC的回收器,默認值是45
-XX:NewRatio=n 老年代和新生代的空間比例,默認值是2,計算公式是NewRatio=老年代/新生代
-XX:SurvivorRatio=n 對象出生地(eden)和幸存區(s0/s1)的的空間比例,默認值是8,計算公式是SurvivorRation=eden/(s0+s1)
-XX:MaxTenuringThreshold=n 最大臨界值,默認是15
-XX: ParallelGCThreads=n 設置垃圾回收器並行階段中使用的線程數,默認值跟平臺相關
-XX:ConcGCThreads=n 並行垃圾回收器的線程數量,默認值跟平臺有關
-XX:G1ReservePercent=n 設置堆的臨時上限,以防止因堆擴大失敗而導致的錯誤。默認值是10
-XX:G1HeapRegionSize=n 使用G1的Java堆細分為均勻大小的區域,這個選項是設置單個區域的大小,這個選項的默認值是基於堆大小進行效率劃分的值來決定(The default value of this parameter is determined ergonomically based upon heap size)。最小值是1Mb並且最大值是32Mb.
性能參數
選項和默認值 描述
-XX:+AggressiveOpts 打開點性能編譯器優化,在未來版本中可能是默認打開(版本5.0更新6中聲明)
-XX:CompileThreshold=10000 在編譯前的方法調用數[-client:1500]
-XX:LargePageSizeInBytes=4m 設置java堆的大頁容量(版本1.4.0更新1中聲明)[amd64:2m]
-XX:MaxHeapFreeRatio=70 GC過後堆的最大空閑空間比例,避免過於壓縮
-XX:MaxNewSize=size 新生代的最大容量,版本1.4後,通過NewRatio函數來計算(1.3.1 Sparc: 32m; 1.3.1 x86: 2.5m)
-XX:MaxPermSize=64M 老年代的最大容量,[5.0以後,64位的VM都擴容了30%,1.4 amd64:96m,1.3.1 -client:32m]
-XX:MinHeapFreeRatio=40 GC過後堆的最小空閑空間比例,避免過於膨脹
-XX:NewRatio=2 老年代和新生代的空間比例,計算公式:NewRatio=老年代/新生代。[Sparc -client:8;x86 -server:8;x86 -client:12] -client:4(1.3)8(1.3.1+),x86:12
-XX:NewSize=2m 新生代的默認容量大小[5.0以後:64位VM擴張30%;x86:1m;x86,5.0之前:640k]
-XX:ReservedCodeCacheSize=32m 保留代碼緩存大小–代碼緩存容量的最大值[Solaris 64位,amd64和 x86 -server:2048m;版本5.0_06以後,Solaris 64位和amd64:1024m]
-XX:SurvivorRatio=8 對象出生地(eden)和幸存區(s0/s1)的空間比例,計算公式:SurvivorRatio=eden/(s0+s1)。[Solaris amd64:6;1.3.1版的Sparc:25;其他Solaris平臺,5.0以前:32]
-XX:TargetSurvivorRatio=50 清理過後幸存區的期望空間大小
-XX:ThreadStackSize=512 線程棧大小.(0表示使用默認值)[Sparc:512;Solaris x86:320(5.0以前的256系列);Sparc 64位:1024;Linux amd64:1024(5.0以前是0);其他都是0]
-XX:+UseBiasedLocking 使用偏向鎖(版本5.0更新6中聲明)[5.0 false]
-XX:+UseFastAccessorMethods 使用Get<基本類型>字段的優化版本
-XX:-UselSM 使用私有共享內存[非Solaris平臺不允許使用]
-XX:+UseLargePages 使用大頁內存(版本5.0更新5中聲明)
-XX:+UseMPSS 使用多頁大小支持W/4MB頁的堆,不要使用ISM,因為這取代了ISM的需要。
-XX:+UseStringCache 啟用對常用分配字符串的緩存
-XX:AllocatePrefetchLines=1 使用JIT編譯代碼生成的預取指令在最後一個對象分配後加載的緩存行數。如果最後一個分配對象是實例,則默認值是1,是數組則為3
-XX:AllocatePrefetchStyle=1 生成預取指令的代碼樣式:0,沒有預取指令生成;1,在每次分配之後執行預取指令; 2,當預取指令執行的時候,使用TLAB分配水印指針(use TLAB allocation watermark pointer to gate )
-XX:+UseCompressedStrings 使用字符串的字節數組來表示ASCII
-XX:+OptimizeStringConcat 盡可能的優化字符串的相關操作
調試選項
選項和默認值 描述
-XX:-CITime 打印JIT編譯器的時間消耗
-XX:ErrorFile=./hs_err_pid.log 如果有錯誤產生,則把錯誤數據保存在對應文件中
-XX:-ExtendedDTraceProbes 打開影響性能追蹤檢測
-XX:HeapDumpPath=./java_pid/hprof 設置導出堆大小的目錄或文件名的路徑
-XX:-HeapDumpOnOutOfMemoryError 當產生內存溢出的時候導出堆信息到文件中
-XX: OnError=”;” 當發生致命錯誤的時候運行用戶定義的命令
-XX: OnOoutOfMemoryError=”;” 當產生內存溢出的時候運行用戶定義的命令
-XX: -PrintClassHistogram 使用Ctrl-Break打斷的時候打印類實例的直方圖
-XX: -PrintConcurrentLocks 使用Ctrl-Break打斷的時候打印java.util.concurrent.Lock信息
-XX: -PrintCommandLineFlags 打印隨命令行而來的標識
-XX: -PrintCompilation 打印方法被編譯時的信息
-XX: -PrintGC 打印進行垃圾回收時的信息
-XX: -PrintGCDetails 打印進行垃圾回收時的詳細信息
-XX: -PrintGCTimeStamps 打印進行垃圾回收時的時間戳
-XX: -PrintTenuringDistribution 打印期限年齡信息(Print tenuring age information)
-XX: -PrintAdaptiveSizePolicy 打印自適應生成大小的信息
-XX:-TraceClassLoading 追蹤類加載信息
-XX:-TraceClassLoadingPreorder 當按引用順序加載的時候追蹤所有類
-XX:-TraceClassResolution 追蹤常量池分解
-XX:-TraceClassUnloading 追蹤卸載類
-XX:-TraceLoaderConstraints 追蹤加載器約束的記錄
-XX:+PerfDataSaveToFile 在退出時保存jvmstat的二進制數據
-XX: ParallelGCThreads=n 設置新生代和老年代中的並行回收器的垃圾回收線程數量,默認值跟平臺有關
-XX:+UserCompressedOops 開啟壓縮指針的使用(對象引用使用32位的偏移量來表示,而不是64位的指針)來優化64位的性能,使得java堆容量小於32gb(Enables the use of compressed pointers (object references represented as 32 bit offsets instead of 64-bit pointers) for optimized 64-bit performance with Java heap sizes less than 32gb)
-XX:+AlwarysPreTouch 在JVM初始化區間預觸摸Java堆,在初始化區間,堆的每一頁都進行了類似的調零,相當於在程序運行時進行增量變化
-XX:AllocatePrefetchDistance=n 設置對象分配的預取間隔。新對象寫入時所用的內存空間都是根據這個值從緩存中來分配,除了最後分配的對象。每個java線程都有自己的分配點。這個選項的默認值跟平臺有關
-XX:InlineSmallCode=n 僅在方法生成的本地字節碼大小小於此之前,內聯先前編譯的方法(Inline a previously compiled method only if its generated native code size is less than this)。默認值跟平臺有關
-XX:MaxInlineSize=35 內聯方法的最大字節碼容量
-XX:FreqInlineSize=n 內聯方法被頻繁執行時的最大字節碼容量
-XX:LoopUnrooLimit=n 在Server模式下的編譯器展開循環體的節點要小於這個選項的值,這個選項的值,在Server模式下的編譯器中是一個函數,而不是一個具體值,這個參數的默認跟平臺有關。
-XX:InitialTenuringThreshold=7 設置年輕代中使用自適應GC大小的並行收集器的初始臨界值(threshold),這個值是一個對象在被推進老年代之前,在年輕代中的幸存次數。
-XX:MaxTenuringThreshold=n 設置使用自定義GC大小的最大臨界值,這個選項的最大值是15,並行收集器的默認值是15而CMS的默認值是4
-Xloggc: 輸出GC詳細日誌到指定文件,具體詳細輸出內容由GC標簽參數決定
-XX:-UseGCLogFileRotation 打開循環輸出GC日誌,同時需要-Xloggc支持
-XX:NumberOfGClogFiles=1 設置循環輸出GC日誌的文件名,必須有一個以上,循環日誌文件的命名需遵從以下規則:.0,.1,…,.n-1。
-XX:GCLogFileSize=8K 日誌文件循環的條件,日誌文件的大小,必須大於等於8k
2、JVM-調優參數-JDK1.8 標準參數
選項和默認值 描述
-d32 使用 32 位數據模型 (如果可用)
-d64 使用 64 位數據模型 (如果可用)
-server 選擇 “server” VM,默認 VM 是 server.
-cp <目錄和 zip/jar 文件的類搜索路徑>
-classpath <目錄和 zip/jar 文件的類搜索路徑>,用 ‘;’ 分隔的目錄, JAR 檔案和 ZIP檔案列表, 用於搜索類文件。
-D<名稱>=<值> 設置系統屬性
-verbose:[class/gc/jni] 啟用詳細輸出
-version 輸出產品版本並退出
-showversion 輸出產品版本並繼續
-?/-help 輸出此幫助消息
-X 輸出非標準選項的幫助
-esa 或 -enablesystemassertions 啟用系統斷言
-dsa 或 -disablesystemassertions 禁用系統斷言
-agentlib:[=<選項>] 加載本機代理庫 , 例如-agentlib:hprof,另請參閱 -agentlib:jdwp=help 和 -agentlib:hprof=help
-agentpath:[=<選項>] 按完整路徑名加載本機代理庫
-javaagent:[=<選項>] 加載 Java 編程語言代理,請參閱java.lang.instrument
-splash: 使用指定的圖像顯示啟動屏幕
非標準參數 來自於’java -X’的幫助信息。
選項和默認值 描述
-Xmixed 混合模式執行 (默認)
-XX:-CITime 打印花費在JIT編譯上的時間
-Xint 僅解釋模式執行
-Xbootclasspath: <用 ; 分隔的目錄和 zip/jar 文件>,設置搜索路徑以引導類和資源
-Xbootclasspath/a: <用 ; 分隔的目錄和 zip/jar 文件>,附加在引導類路徑末尾
-Xbootclasspath/p: <用 ; 分隔的目錄和 zip/jar 文件>,置於引導類路徑之前
-Xdiag 顯示附加診斷消息
-Xnoclassgc 禁用類垃圾收集
-Xincgc 啟用增量垃圾收集
-Xloggc: 將 GC 狀態記錄在文件中 (帶時間戳)
-Xbatch 禁用後臺編譯
-Xmn 設置新生代的初始值和最大值,單位默認是字節,可以使用k,m,g
-Xms 設置初始 Java 堆大小,單位默認是字節,可以使用k,m,g
-Xmx 設置最大 Java 堆大小,單位默認是字節,可以使用k,m,g
-Xss 設置 Java 線程堆棧大小,單位默認是字節,可以使用k,m,g
-Xprof 輸出 cpu 配置文件數據
-Xfuture 啟用最嚴格的檢查, 預期將來的默認值
-Xrs 減少 Java/VM 對操作系統信號的使用 (請參閱相關文檔)
-Xcheck:jni 對 JNI 函數執行其他檢查
-Xshare: off 不嘗試使用共享類數據
-Xshare:auto 在可能的情況下使用共享類數據 (默認)
-Xshare: on 要求使用共享類數據, 否則將失敗。
-XshowSettings 顯示所有設置並繼續
-XshowSettings:all 顯示所有設置並繼續
-XshowSettings:vm 顯示所有與 vm 相關的設置並繼續
-XshowSettings:properties 顯示所有屬性設置並繼續
-XshowSettings:locale 顯示所有與區域設置相關的設置並繼續
jdk1.8中廢棄並刪除的選項
  • ‘-Xincgc’
  • ‘-Xrunlibname’
  • ‘-XX:CMSIncrementalDutyCycle=percent’
  • ‘-XX:CMSIncrementalDutyCycleMin=percent’
  • ‘-XX:+CMSIncrementalMode’
  • ‘-XX:CMSIncrementalOffset=percent’
  • ‘-XX:+CMSIncrementalPacing’
  • ‘-XX:CMSIncrementalSafetyFactor=percent’
  • ‘-XX:CMSInitiatingPermOccupancyFraction=percent’
  • ‘-XX:MaxPermSize=size’
  • ‘-XX: PermSize=size’
  • ‘-XX:+UseSplitVerifier’
  • ‘-XX:+UseStringCache’
四、GC性能方面的考慮 不管是minor GC、major GC和full GC,GC過程中都會對導致程序運行中中斷,正確的選擇不同的GC策略,調整JVM、GC的參數,可以極大的減少由於GC工作而導致的程序運行中斷方面的問題,進而適當的提高Java程序的工作效率。但是調整GC是以個極為復雜的過程,由於各個程序具備不同的特點,如:web和GUI程序就有很大區別(Web可以適當的停頓,但GUI停頓是客戶無法接受的),而且由於跑在各個機器上的配置不同(主要cup個數,內存不同),所以使用的GC種類也會不同。 對於GC的性能主要有2個方面的指標:吞吐量throughput(工作時間不算gc的時間占總的時間比)和暫停pause(gc發生時app對外顯示的無法響應)。 五、JVM參數配置的經驗&&規則
  1. 年輕代和老年代的大小
可能很多人都有一種印象,young gen應該比old gen小。籠統說確實如此,因為在最壞情況下young gen裏可能所有對象都還活著,而如果它們全部都要晉升到old gen的話,那old gen裏的剩余空間必須能容納下這些對象才行,這就需要old gen比young gen大(否則young GC就無法進行,而必須做full GC才能應付了)。
實際上卻不總是這樣的。所謂“最壞情況”在很多系統裏是永遠不會出現的。調優就是要針對實際應用裏對象的存活模式來破除這些“最壞情況”的假設帶來的限制。
許多Web應用裏對象會有這樣的特征:
·(a) 有一部分對象幾乎一直活著。這些可能是常用數據的cache之類的
·(b) 有一部分對象創建出來沒多久之後就沒用了。這些很可能會響應一個請求時創建出來的臨時對象
·(c) 最後可能還有一些中間的對象,創建出來之後不會馬上就死,但也不會一直活著。
如果是這樣的模式,那young gen可以設置得非常大,大到每次young GC的時候裏面的多數(b)類對象最好已經死了。
想像一下,如果young gen太小,每次滿了就觸發一次young GC,那麽young GC就會很頻繁,或許很多臨時對象(b)正好還在被是使用(還沒死),這樣的話young GC的收集效率就會比較低。要避免這樣的情況,最好是就是把young gen設大一些。
那old gen怎麽辦?如果是上面說的情況,那old gen至少要足以裝下所有長期存活的對象(a);同時也要留出一定的余地用來容納young GC沒能清理掉的臨時對象。 這樣,最後調整出來的結果很可能young GC反而比old gen大許多。這完全沒問題。
  1. 較小堆引起的碎片問題
因為年老代的並發收集器使用標記,清除算法,所以不會對堆進行壓縮.當堆空間較小時,運行一段時間以後,就會出現"碎片",如果並發收集器找不到足夠的空間,那麽並發收集器將會停止,然後使用傳統的標記,清除方式進行回收.
-XX:+UseCMSCompactAtFullCollection:使用並發收集器時,開啟對年老代的壓縮.
-XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這裏設置多少次Full GC後,對年老代進行壓縮
  1. 用64位操作系統,Linux下64位的jdk比32位jdk要慢一些,但是吃得內存更多,吞吐量更大
  1. XMX和XMS設置一樣大,MaxPermSize和MinPermSize設置一樣大,這樣可以減輕伸縮堆大小帶來的壓力
  1. 使用CMS的好處是老生代利用CMS並行收集, 這樣能保證系統低延遲的吞吐效率。 實際上cms的收集停頓時間非常的短,2G的內存, 大約20-80ms的應用程序停頓時間
  1. 系統停頓的時候可能是GC的問題也可能是程序的問題,多用jmap和jstack查看,然後查看java控制臺日誌,能看出很多問題。(相關工具的使用方法將在後面介紹)
  1. 仔細了解自己的應用,如果用了緩存,那麽年老代應該大一些,緩存的HashMap不應該無限制長,最大長度也要根據實際情況設定。
  1. 采用並發回收時,年輕代小一點,年老代要大,因為老年代大用的是並發回收,即使時間長點也不會影響其他程序繼續運行,網站不會停頓
  1. JVM參數的設置(特別是 –Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等參數的設置沒有一個固定的公式,需要根據PV,old區實際數據 YGC次數等多方面來衡量。xmn設置偏小,也意味著YGC的次數會增多,處理並發訪問的能力下降等問題。每個參數的調整都需要經過詳細的性能測試,才能找到特定應用的最佳配置。
六、生產環境JVM參數實戰
jdk 1.7 生產虛擬機參數(添加到 catalina.sh中)
JAVA_OPTS=-Xmx8000M -Xms8000M -Xmn1024M -XX:PermSize=2048M -XX:MaxPermSize=2048M -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:/tmp/gc.log
jdk 1.8 (註意新版本metaspace 代替了舊版本PermGen space)
JAVA_OPTS=-server -Xmx8g -Xms8g -Xmn2g -XX:MetaspaceSize=2g -XX:MaxMetaspaceSize=2g -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Duser.timezone=GMT+8 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/b2b_interface.dump -Xloggc:/tmp/b2b_interface_gc.log -verbose:gc -Xmixed -XX:-CITime
set JAVA_OPTS=%JAVA_OPTS% -server -Xmx1000m -Xms1000m -Xmn250m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Duser.timezone=GMT+8 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/b2b_interface.dump -Xloggc:/b2b_interface_gc.log -verbose:gc -Xmixed -XX:-CITime

JVM調優參數匯總