jvm 記憶體模型及引數
0、記憶體模型圖
堆記憶體圖
1、常用引數
堆記憶體分配:
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。
-Xmn2G:設定年輕代大小為2G。
-XX:SurvivorRatio,設定年輕代中Eden區與Survivor區的比值。
2、幾種gc
GC 會 Stop-The-World。
young GC =Minor GC
young GC(新生代GC):指發生在新生代的垃圾收集動作,新生代中的物件朝生夕死,所以 Minor GC 非常頻繁,回收速度也比較快。採用複製演算法來回收新生代的垃圾。
Full GC(老年代GC):指發生在老年代的GC,速度一般比 Minor GC 慢十倍以上。Full GC 會 Stop-The-World。
Full GC會包含Young GC、Old GC和永久代的GC。
3、什麼時候會觸發Full GC?
呼叫 System.gc() 方法時,會建議JVM進行Full GC,此方法不建議使用。
新生代使用的是複製演算法,為了記憶體利用率,只使用其中一個 Survivor 空間來做輪換備份,因此如果大量物件在 Minor GC 後仍然存活,導致 Survivor 空間不夠用,就會通過分配擔保機制,將多出來的物件提前轉到老年代,此時如果老年代的可用記憶體小於該物件的大小,就會觸發 Full GC。
當老年代中最大可用的連續空間小於歷代晉升到老年代的物件的平均大小時,會觸發Full GC 來讓老年代騰出更多的空間。
4、如何優化GC?
- 儘量不要建立過大的物件或陣列。
- 通過虛擬機器的 -Xmn 引數適當調大新生代的大小,讓物件儘量在新生代中被回收掉。
- 通過 -XX:MaxTenuringThreshold 引數調大物件進入老年代的年齡,讓物件儘量在新生代中被回收掉。