1. 程式人生 > 其它 >JVM介紹及引數配置

JVM介紹及引數配置

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的物件就會進入老年代);
JVM年輕代垃圾回收: 新物件首先在eden區分配空間,當eden區滿時,還存活的物件將被複制到一個survivor區。當這個survivor區滿時,存活物件會被複制到另一個survivor區。當第二個survivor區也滿了時,存活物件被複制到老年代。 2個survivor區是完全對稱的,輪流替換。 觸發FGC的三種情況
  • 老年代滿了之後,觸發FGC;
  • 被顯示呼叫的時候會觸發FGC(runtime.gc() system.gc());
  • 悲觀策略(基於rmi的框架,框架中會定義隔一段時間在程式碼中顯示呼叫system.gc())也會呼叫FGC;
  • jmap -dump 也會觸發FGC
調優方法: 一般情況:
  • 多數的Java應用不需要在伺服器上進行GC優化;
  • 多數導致GC問題的Java應用,都不是因為我們引數設定錯誤,而是程式碼問題;
  • 在應用上線之前,先考慮將機器的JVM引數設定到最優(最適合);
  • 減少建立物件的數量;
  • 減少使用全域性變數和大物件;
  • GC優化是到最後不得已才採用的手段;
  • 在實際使用中,分析GC情況優化程式碼比優化GC引數要多得多;
GC優化的目的有兩個:
  • 將轉移到老年代的物件數量降低到最小;
  • 減少full GC的執行時間
為了達到上面的目的,一般地,需要做的事情有:
  • 減少使用全域性變數和大物件;
  • 調整新生代的大小到最合適;
  • 設定老年代的大小為最合適;
  • 選擇合適的GC收集器;
1. 不管是YGC還是Full GC,GC過程中都會對導致程式執行中中斷,正確的選擇不同的GC策略,調整JVM、GC的引數,可以極大的減少由於GC工作,而導致的程式執行中斷方面的問題,進而適當的提高Java程式的工作效率; 2. FGC會對整個堆和非堆(包含持久帶)進行垃圾回收 ; 3. YGC只會對伊甸園區和存活區進行垃圾回收;
引數名稱 含義 預設值 備註
-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