JVM介紹及引數配置
阿新 • • 發佈:2021-07-30
1.堆記憶體和非堆記憶體組成
堆記憶體:分為年輕代和老年代
年輕代:Eden區和兩個存活區
Q:為什麼對堆要分年輕代,老年代,伊甸園區,存活區?
A:減少FGC的頻率,減少程式暫停的時間,提高效能,如果不分割槽,很快堆記憶體滿了就會觸發GC,對整個堆進行垃圾回收,而堆記憶體較大,會耗費很長時間,程式暫停時間過長,影響效能
2.堆記憶體存放的是new出來的物件和陣列
非堆記憶體存放的是常量、靜態變數、方法區、記憶體計數器
3.棧是執行時的單位,而堆是儲存的單位。
棧解決程式的執行問題,即程式如何執行,或者說如何處理資料;堆解決的是資料儲存的問題,而資料怎麼放、放在哪兒。
棧:執行
堆:儲存
4.JVM heap記憶體空間劃分
分配原則:
- 物件優先在Eden中分配,當伊甸園區滿了之後會觸發YGC,YGC進行尋根判斷,被引用的物件進入存活區,未被引用的物件被當做垃圾回收
當Survivor中放不下時,則由分派擔保進入老年代中。 - 大物件直接進入老年代中。 -XX:+PretenuerSizeThreshold 控制”大物件的“的大小,如果物件大小大於設定值直接放入老年代。
- 長期存活的物件將進入老年代(預設age=15的物件叫長期存活物件,也可以用引數進行配置);
- 動態物件年齡判定:虛擬機器並不總是要求物件的年齡必須達到MaxTenuringThreshold才能晉升到老年代,如果在Survivor區中相同年齡的物件的所有大小之和超過Survivor空間的一半,年齡大於或等於該年齡的物件就可以直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡(如age=5的物件很多,加起來大於存活區大小的一半了,那些age>=5的物件就會進入老年代);
- 老年代滿了之後,觸發FGC;
- 被顯示呼叫的時候會觸發FGC(runtime.gc() system.gc());
- 悲觀策略(基於rmi的框架,框架中會定義隔一段時間在程式碼中顯示呼叫system.gc())也會呼叫FGC;
- jmap -dump 也會觸發FGC
- 多數的Java應用不需要在伺服器上進行GC優化;
- 多數導致GC問題的Java應用,都不是因為我們引數設定錯誤,而是程式碼問題;
- 在應用上線之前,先考慮將機器的JVM引數設定到最優(最適合);
- 減少建立物件的數量;
- 減少使用全域性變數和大物件;
- GC優化是到最後不得已才採用的手段;
- 在實際使用中,分析GC情況優化程式碼比優化GC引數要多得多;
- 將轉移到老年代的物件數量降低到最小;
- 減少full GC的執行時間;
- 減少使用全域性變數和大物件;
- 調整新生代的大小到最合適;
- 設定老年代的大小為最合適;
- 選擇合適的GC收集器;
引數名稱 | 含義 | 預設值 | 備註 |
-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 |