1、Java虛擬機運行時的數據區
2、常用的內存區域調節參數
-Xms :初始堆大小,默認為物理內存的1/64(<1GB);默認(MinHeapFreeRatio參數可以調整)空余堆內存小于40%時,JVM就會增大堆直到-Xmx的最大限制
-Xmx :最大堆大小,默認(MaxHeapFreeRatio參數可以調整)空余堆內存大于70%時,JVM會減少堆直到 -Xms的最小限制
-Xmn
:新生代的內存空間大小,
注意
:此處的大小是(eden+ 2 survivor space)。與jmap -heap中顯示的New gen是不同的。整個堆大小=新生代大小 + 老生代大小 + 永久代大小。?
在保證堆大小不變的情況下,增大新生代后,將會減小老生代大小。此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8。
-XX:SurvivorRatio :新生代中Eden區域與Survivor區域的容量比值,默認值為8。兩個Survivor區與一個Eden區的比值為2:8,一個Survivor區占整個年輕代的1/10。
-Xss :每個線程的堆棧大小。JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K。應根據應用的線程所需內存大小進行適當調整。在相同物理內存下,減小這個值能生成更多的線程。但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在3000~5000左右。一般小的應用, 如果棧不是很深, 應該是128k夠用的,大的應用建議使用256k。這個選項對性能影響比較大,需要嚴格的測試。和threadstacksize選項解釋很類似,官方文檔似乎沒有解釋,在論壇中有這樣一句話:"-Xss is translated in a VM flag named ThreadStackSize”一般設置這個值就可以了。
-XX:PermSize :設置永久代(perm gen)初始值。默認值為物理內存的1/64。
-XX:MaxPermSize :設置持久代最大值。物理內存的1/4。
3、內存分配方法
1)堆上分配?? 2)棧上分配? 3)堆外分配(DirectByteBuffer或直接使用Unsafe.allocateMemory,但不推薦這種方式)
4、監控方法
1)系統程序運行時可通過jstat –gcutil來查看堆中各個內存區域的變化以及GC的工作狀態;?
2)啟動時可添加-XX:+PrintGCDetails? –Xloggc:<file>輸出到日志文件來查看GC的狀況;?
3)jmap –heap可用于查看各個內存空間的大小;
5)斷代法可用GC匯總
一、新生代可用GC
1)串行GC(Serial Copying):client模式下默認GC方式,
也可通過-XX:+UseSerialGC來強制指定
;默認情況下 eden、s0、s1的大小通過-XX:SurvivorRatio來控制,默認為8,含義?
為eden:s0的比例,啟動后可通過jmap –heap [pid]來查看。
????? 默認情況下,僅在TLAB或eden上分配,只有兩種情況下會在老生代分配:?
?????
?1、需要分配的內存大小超過eden space大小;?
????
? 2、在配置了PretenureSizeThreshold的情況下,對象大小大于此值。 -XX:PretenureSizeThreshold=3M
????? 默認情況下,觸發Minor GC時:?
????? 之前Minor GC晉級到old的平均大小 < 老生代的剩余空間 < eden+from Survivor的使用空間。當HandlePromotionFailure為true,則僅觸發minor gc;如為false,則觸發full GC。
????? 默認情況下,新生代對象晉升到老生代的規則:
????
?1、經歷多次minor gc仍存活的對象,可通過以下參數來控制:以MaxTenuringThreshold值為準,默認為15。?
???
? 2、to space放不下的,直接放入老生代;
2)并行GC(ParNew):CMS GC時默認采用, 也可采用-XX:+UseParNewGC強制指定 ;垃圾回收的時候采用多線程的方式。
3)并行回收GC(Parallel Scavenge):server模式下默認的GC方式,
也可采用-XX:+UseParallelGC強制指定
;eden、s0、s1的大小可通過-XX:SurvivorRatio來控制,但默認情況下?
以-XX:InitialSurivivorRatio為準,此值默認為8,
代表的為新生代大小 : s0
,這點要特別注意。
????? 默認情況下,當TLAB、eden上分配都失敗時,判斷需要分配的內存大小是否 >= eden space的一半大小,如是就直接在老生代上分配;
????? 默認情況下的垃圾回收規則:
????? 1、在回收前PS GC會先檢測之前每次PS GC時,晉升到老生代的平均大小是否大于老生代的剩余空間,如大于則直接觸發full GC;?
????? 2、在回收后,也會按照上面的規則進行檢測。
????? 默認情況下的新生代對象晉升到老生代的規則:?
???? 1、經歷多次minor gc仍存活的對象,可通過以下參數來控制:AlwaysTenure,默認false,表示只要minor GC時存活,就晉升到老生代;NeverTenure,默認false,表示永不晉升到老生代;上面兩個都沒設置的情冴下,如UseAdaptiveSizePolicy,啟動時以InitialTenuringThreshold值作為存活次數的閾值,在每次ps gc后會動態調整,如不使用UseAdaptiveSizePolicy,則以MaxTenuringThreshold為準。?
???? 2、to space放不下的,直接放入老生代。
???? 在回收后,如UseAdaptiveSizePolicy,PS GC會根據運行狀態動態調整eden、to以及TenuringThreshold的大小。如果不希望動態調整可設置-XX:-UseAdaptiveSizePolicy。如希望跟蹤每次的變化情況,可在啟勱參數上增加: PrintAdaptiveSizePolicy。
二、老生代可用GC
1、串行GC(Serial Copying):client方式下默認GC方式,可通過-XX:+UseSerialGC強制指定。
??? 觸發機制匯總:?
?
? 1)old gen空間不足;?
?? 2)perm gen空間不足;?
?? 3)minor gc時的悲觀策略;?
?? 4)minor GC后在eden上分配內存仍然失敗;?
?? 5)執行heap dump時;?
?? 6)外部調用System.gc,可通過-XX:+DisableExplicitGC來禁止。
2、并行回收GC(Parallel Scavenge): server模式下默認GC方式,可通過-XX:+UseParallelGC強制指定; 并行的線程數為當cpu core<=8 ? cpu core : 3+(cpu core*5)/8或通過 -XX:ParallelGCThreads=x 來強制指定。如ScavengeBeforeFullGC為true(默認值),則先執行minor GC。
3、并行Compacting:可通過 -XX:+UseParallelOldGC 強制指定。
4、并發CMS:可通過 -XX:+UseConcMarkSweepGC 來強制指定。并發的線程數默認為:( 并行GC線程數+3)/4,也可通過ParallelCMSThreads指定。
??? 觸發機制:?
??? 1、當老生代空間的使用到達一定比率時觸發;
???? Hotspot V 1.6中默認為65%,可通過PrintCMSInitiationStatistics(此參數在V 1.5中不能用)來查看這個值到底是多少;可通過CMSInitiatingOccupancyFraction來強制指定,默認值并不是賦值在了這個值上,是根據如下公式計算出來的: ((100 - MinHeapFreeRatio) +(double)(CMSTriggerRatio * MinHeapFreeRatio) / 100.0)/ 100.0; 其中,MinHeapFreeRatio默認值: 40?? CMSTriggerRatio默認值: 80。
???? 2、當perm gen采用CMS收集且空間使用到一定比率時觸發;
???? perm gen采用CMS收集需設置:-XX:+CMSClassUnloadingEnabled?? Hotspot V 1.6中默認為65%;可通過CMSInitiatingPermOccupancyFraction來強制指定,同樣,它是根據如下公式計算出來的:((100 - MinHeapFreeRatio) +(double)(CMSTriggerPermRatio* MinHeapFreeRatio) / 100.0)/ 100.0; 其中,MinHeapFreeRatio默認值: 40??? CMSTriggerPermRatio默認值: 80。
????? 3、Hotspot根據成本計算決定是否需要執行CMS GC;可通過-XX:+UseCMSInitiatingOccupancyOnly來去掉這個動態執行的策略。?
????? 4、外部調用了System.gc,且設置了ExplicitGCInvokesConcurrent;需要注意,在hotspot 6中,在這種情況下如應用同時使用了NIO,可能會出現bug。
6、GC組合
1)默認GC組合
2)可選的GC組合
7、GC監測
1)jstat –gcutil [pid] [intervel] [count]?
2)-verbose:gc // 可以輔助輸出一些詳細的GC信息;-XX:+PrintGCDetails // 輸出GC詳細信息;-XX:+PrintGCApplicationStoppedTime // 輸出GC造成應用暫停的時間?
-XX:+PrintGCDateStamps // GC發生的時間信息;-XX:+PrintHeapAtGC // 在GC前后輸出堆中各個區域的大小;-Xloggc:[file] // 將GC信息輸出到單獨的文件中,建議都加上,這個消耗不大,而且對查問題和調優有很大的幫助。gc的日志拿下來后可使用GCLogViewer或gchisto進行分析。?
3)圖形化的情況下可直接用jvisualvm進行分析。
4)查看內存的消耗狀況
????? (1)長期消耗,可以直接dump,然后MAT(內存分析工具)查看即可
????? (2)短期消耗,圖形界面情況下,可使用jvisualvm的memory profiler或jprofiler。
8、系統調優方法
步驟:1、評估現狀 2、設定目標 3、嘗試調優 4、衡量調優 5、細微調整
設定目標:
1)降低Full GC的執行頻率??
2)降低Full GC的消耗時間??
3)降低Full GC所造成的應用停頓時間??
4)降低Minor GC執行頻率??
5)降低Minor GC消耗時間??
例如某系統的GC調優目標:降低Full GC執行頻率的同時,盡可能降低minor GC的執行頻率、消耗時間以及GC對應用造成的停頓時間。
衡量調優:
1、衡量工具?
1)打印GC日志信息:-XX:+PrintGCDetails –XX:+PrintGCApplicationStoppedTime -Xloggc: {文件名}? -XX:+PrintGCTimeStamps?
2)jmap:(由于每個版本jvm的默認值可能會有改變,建議還是用jmap首先觀察下目前每個代的內存大小、GC方式) ??
3)運行狀況監測工具:jstat、jvisualvm、sar 、gclogviewer
2、應收集的信息?
1)minor gc的執行頻率;full gc的執行頻率,每次GC耗時多少??
2)高峰期什么狀況??
3)minor gc回收的效果如何?survivor的消耗狀況如何,每次有多少對象會進入老生代??
4)full gc回收的效果如何?(簡單的
memory leak
判斷方法)?
5)系統的load、cpu消耗、qps or tps、響應時間
QPS每秒查詢率:是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。在因特網上,作為域名服務器的機器性能經常用每秒查詢率來衡量。對應fetches/sec,即每秒的響應請求數,也即是最大吞吐能力。?
TPS(Transaction Per Second):每秒鐘系統能夠處理的交易或事務的數量。
嘗試調優:
注意Java RMI的定時GC觸發機制,可通過:-XX:+DisableExplicitGC來禁止或通過 -Dsun.rmi.dgc.server.gcInterval=3600000來控制觸發的時間。
1)降低Full GC執行頻率 – 通常瓶頸?
老生代本身占用的內存空間就一直偏高,所以只要稍微放點對象到老生代,就full GC了;?
通常原因:系統緩存的東西太多;?
例如:使用oracle 10g驅動時preparedstatement cache太大;?
查找辦法:現執行Dump然后再進行MAT分析;
(1)Minor GC后總是有對象不斷的進入老生代,導致老生代不斷的滿?
通常原因:Survivor太小了?
系統表現:系統響應太慢、請求量太大、每次請求分配的內存太多、分配的對象太大...?
查找辦法:分析兩次minor GC之間到底哪些地方分配了內存;?
利用jstat觀察Survivor的消耗狀況,-XX:PrintHeapAtGC,輸出GC前后的詳細信息;?
對于系統響應慢可以采用系統優化,不是GC優化的內容;
(2)老生代的內存占用一直偏高?
調優方法:① 擴大老生代的大小(減少新生代的大小或調大heap的 大小);?
減少new注意對minor gc的影響并且同時有可能造成full gc還是嚴重;?
調大heap注意full gc的時間的延長,cpu夠強悍嘛,os是32 bit的嗎??
② 程序優化(去掉一些不必要的緩存)
(3)Minor GC后總是有對象不斷的進入老生代?
前提:這些進入老生代的對象在full GC時大部分都會被回收?
調優方法:?
① 降低Minor GC的執行頻率;?
② 讓對象盡量在Minor GC中就被回收掉:增大Eden區、增大survivor、增大TenuringThreshold;注意這些可能會造成minor gc執行頻繁;?
③ 切換成CMS GC:老生代還沒有滿就回收掉,從而降低Full GC觸發的可能性;?
④ 程序優化:提升響應速度、降低每次請求分配的內存、
(4)降低單次Full GC的執行時間?
通常原因:老生代太大了...?
調優方法:1)是并行GC嗎??? 2)升級CPU? 3)減小Heap或老生代
(5)降低Minor GC執行頻率?
通常原因:每次請求分配的內存多、請求量大?
通常辦法:1)擴大heap、擴大新生代、擴大eden。注意點:降低每次請求分配的內存;橫向增加機器的數量分擔請求的數量。
(6)降低Minor GC執行時間?
通常原因:新生代太大了,響應速度太慢了,導致每次Minor GC時存活的對象多?
通常辦法:1)減小點新生代吧;2)增加CPU的數量、升級CPU的配置;加快系統的響應速度
細微調整:
首先需要了解以下情況:
① 當響應速度下降到多少或請求量上漲到多少時,系統會宕掉?
② 參數調整后系統多久會執行一次Minor GC,多久會執行一次Full GC,高峰期會如何?
需要計算的量:
①每次請求平均需要分配多少內存?系統的平均響應時間是多少呢?請求量是多少、多常時間執行一次Minor GC、Full GC?
②現有參數下,應該是多久一次Minor GC、Full GC,對比真實狀況,做一定的調整;
必殺技:提升響應速度、降低每次請求分配的內存?
9、系統調優舉例
???? 現象:1、系統響應速度大概為100ms;2、當系統QPS增長到40時,機器每隔5秒就執行一次minor gc,每隔3分鐘就執行一次full gc,并且很快就一直full GC了;4、每次Full gc后舊生代大概會消耗400M,有點多了。
???? 解決方案:解決Full GC次數過多的問題
??? (1)降低響應時間或請求次數,這個需要重構,比較麻煩;——這個是終極方法,往往能夠順利的解決問題,因為大部分的問題均是由程序自身造成的。
??? (2)減少老生代內存的消耗,比較靠譜;——可以通過分析Dump文件(jmap dump),并利用MAT查找內存消耗的原因,從而發現程序中造成老生代內存消耗的原因。
??? (3)減少每次請求的內存的消耗,貌似比較靠譜;——這個是海市蜃樓,沒有太好的辦法。
??? (4)降低GC造成的應用暫停的時間——可以采用CMS GS垃圾回收器。參數設置如下:
???? -Xms1536m -Xmx1536m -Xmn700m -XX:SurvivorRatio=7 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection
???? -XX:CMSMaxAbortablePrecleanTime=1000 -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC
??? (5)減少每次minor gc晉升到old的對象。可選方法:1) 調大新生代。2)調大Survivor。3)調大TenuringThreshold。
????? 調大Survivor:當前采用PS GC,Survivor space會被動態調整。由于調整幅度很小,導致了經常有對象直接轉移到了老生代;于是禁止Survivor區的動態調整了,-XX:-UseAdaptiveSizePolicy,并計算Survivor Space需要的大小,于是繼續觀察,并做微調…。最終將Full GC推遲到2小時1次。
10、垃圾回收的實現原理
????? 內存回收的實現方法:1)引用計數:不適合復雜對象的引用關系,尤其是循環依賴的場景。2)有向圖Tracing:適合于復雜對象的引用關系場景,Hotspot采用這種。常用算法:Copying、Mark-Sweep、Mark-Compact。
????? Hotspot從root set開始掃描有引用的對象并對Reference類型的對象進行特殊處理。?
????? 以下是Root Set的列表:1)當前正在執行的線程;2)全局/靜態變量;3)JVM Handles;4)JNI 【 Java Native Interface 】Handles;
????? 另外:minor GC只掃描新生代,當老生代的對象引用了新生代的對象時,會采用如下的處理方式:在給對象賦引用時,會經過一個write barrier的過程,以便檢查是否有老生代引用新生代對象的情況,如有則記錄到remember set中。并在minor gc時,remember set指向的新生代對象也作為root set。
????? 新生代串行GC(Serial Copying):
???? 新生代串行GC(Serial Copying)完整內存的分配策略:
???? 1)首先在TLAB(本地線程分配緩沖區)上嘗試分配;?
???? 2)檢查是否需要在新生代上分配,如需要分配的大小小于PretenureSizeThreshold,則在eden區上進行分配,分配成功則返回;分配失敗則繼續;?
???? 3)檢查是否需要嘗試在老生代上分配,如需要,則遍歷所有代并檢查是否可在該代上分配,如可以則進行分配;如不需要在老生代上嘗試分配,則繼續;?
???? 4)根據策略決定執行新生代GC或Full GC,執行full gc時不清除soft Ref;?
???? 5)如需要分配的大小大于PretenureSizeThreshold,嘗試在老生代上分配,否則嘗試在新生代上分配;?
???? 6)嘗試擴大堆并分配;?
???? 7)執行full gc,并清除所有soft Ref,按步驟5繼續嘗試分配。??
???? 新生代串行GC(Serial Copying)完整內存回收策略?
???? 1)檢查to是否為空,不為空返回false;?
???? 2)檢查老生代剩余空間是否大于當前eden+from已用的大小,如大于則返回true,如小于且HandlePromotionFailure為true,則檢查剩余空間是否大于之前每次minor gc晉級到老生代的平均大小,如大于返回true,如小于返回false。?
???? 3)如上面的結果為false,則執行full gc;如上面的結果為true,執行下面的步驟;?
???? 4)掃描引用關系,將活的對象copy到to space,如對象在minor gc中的存活次數超過tenuring_threshold或分配失敗,則往老生代復制,如仍然復制失敗,則取決于HandlePromotionFailure,如不需要處理,直接拋出OOM,并退出vm,如需處理,則保持這些新生代對象不動;
???? 新生代可用GC-PS
??? 完整內存分配策略?
??? 1)先在TLAB上分配,分配失敗則直接在eden上分配;?
??? 2)當eden上分配失敗時,檢查需要分配的大小是否 >= eden space的一半,如是,則直接在老生代分配;?
??? 3)如分配仍然失敗,且gc已超過頻率,則拋出OOM;?
??? 4)進入基本分配策略失敗的模式;?
??? 5)執行PS GC,在eden上分配;?
??? 6)執行非最大壓縮的full gc,在eden上分配;?
??? 7)在舊生代上分配;?
??? 8)執行最大壓縮full gc,在eden上分配;?
??? 9)在舊生代上分配;?
??? 10)如還失敗,回到2。
?? 最悲慘的情況,分配觸發多次PS GC和多次Full GC,直到OOM。
?? 完整內存回收策略?
?? 1)如gc所執行的時間超過,直接結束;?
?? 2)先調用invoke_nopolicy?
?????? 2.1 先檢查是不是要嘗試scavenge;?
?????? 2.1.1 to space必須為空,如不為空,則返回false;?
?????? 2.1.2 獲取之前所有minor gc晉級到old的平均大小,并對比目前eden+from已使用的大小,取更小的一個值,如老生代剩余空間小于此值,則返回false,如大于則返回true;?
?????? 2.2 如不需要嘗試scavenge,則返回false,否則繼續;?
?????? 2.3 多線程掃描活的對象,并基亍copying算法回收,回收時相應的晉升對象到舊生代;?
?????? 2.4 如UseAdaptiveSizePolicy,那么重新計算to space和tenuringThreshold的值,并調整。?
?? 3)如invoke_nopolicy返回的是false,或之前所有minor gc晉級到老生代的平均大小 > 舊生代的剩余空間,那么繼續下面的步驟,否則結束;?
?? 4)如UseParallelOldGC,則執行PSParallelCompact,如不是UseParallelOldGC,則執行PSMarkSweep。
???? 老生代并行CMS GC:
??? 優缺點:
????
1) 大部分時候和應用并發進行,因此只會造成很短的暫停時間;?
??? 2)浮動垃圾,沒辦法,所以內存空間要稍微大一點;?
??? 3)內存碎片,-XX:+UseCMSCompactAtFullCollection 來解決;?
??? 4) 爭搶CPU,這GC方式就這樣;?
??? 5)多次remark,所以總的gc時間會比并行的長;?
??? 6)內存分配,free list方式,so性能稍差,對minor GC會有一點影響;?
??? 7)和應用并發,有可能分配和回收同時,產生競爭,引入了鎖,JVM分配優先。
11、TLAB的解釋
???? 堆內的對象數據是各個線程所共享的,所以當在堆內創建新的對象時,就需要進行鎖操作。鎖操作是比較耗時,因此JVM為每個線在堆上分配了一塊“自留地”——TLAB(全稱是Thread Local Allocation Buffer),位于堆內存的新生代,也就是Eden區。每個線程在創建新的對象時,會首先嘗試在自己的TLAB里進行分配,如果成功就返回,失敗了再到共享的Eden區里去申請空間。在線程自己的TLAB區域創建對象失敗一般有兩個原因:一是對象太大,二是自己的TLAB區剩余空間不夠。通常默認的TLAB區域大小是Eden區域的1%,當然也可以手工進行調整,對應的JVM參數是-XX:TLABWasteTargetPercent。
附表:
?
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 |
? |
并行收集器相關參數
參數名稱 | 含義 | 默認值 | ? |
-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 | ? |
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 | ? | ? |
輸出形式:
[GC 118250K->113543K(130112K), 0.0094143 secs]
|
-XX:+PrintGCDetails | ? | ? |
輸出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 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)
? |
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
