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 參數調大對象進入老年代的年齡,讓對象盡量在新生代中被回收掉。