1.JVM垃圾回收機制
1.1 標記算法
- 引用計數法(進行對象引用計數)——缺點是無法進行解決循環引用
- 可達性分析——通過一個圖,進行從root節點往下進行遍歷,沒有遍歷到的就是無引用對象
1.2 回收算法
- 標記-清除法——分爲標記,清除兩個算法,先一層循環進行標記,再一層循環進行清除
- 複製算法——進行將內存分爲兩塊,一塊進行使用,使用完進行一次回收
- 標記整理——一輪循環標記,一輪進行交換位置,將不使用的放在末端,最後再全部回收(解決內存碎片化的問題)
- 分代收集算法——分爲新生代,老年代,新生代有Eden, From Survivor, To Survivor區域,老年代有Tenured Gen區域
- Eden空間和Survivor空間的默認大小比例是8:1,可通過 -XX:SurvivorRatio 命令調整這個比例。
- 新生代和老年代默認內存大小的比例是1:2,可用過 -XX:NewRatio 命令調整這個比例。
- 經歷一定Minor次數依然存活的對象,該次數可通過 -XX:MaxTenuringThreshold 命令調整,默認:15。
- Survivor空間中存放不下的對象,會存儲在老年代。
- 新生成的大對象會存儲在老年代中,可通過 -XX:+PretenuerSizeThreshold 命令調整。
- GC的分類
- Minor GC:從新生代回收內存。
- Full GC:回收整個Java堆空間的內存,包括新生代和老年代。Full GC比Minor GC慢很多,大概有10倍的差距,但是Full GC執行的頻率比較低。
- Major GC:一般來說和Full GC是等價的,由於名詞解讀的混亂,當說Major GC時一定要問清楚是指Full GC還是僅指從老年代回收內存。
- 觸發Full GC的條件:
- 老年代空間不足
- 永久代空間不足
- CMS GC時出現promotion failed,concurrent mode failure時
- Minor GC晉升到老年代的平均大小大於老年代的剩餘空間
- 調用System.gc()
- 使用RMI來進行RPC或管理的JDK應用,沒小時執行一次Full GC
1.3 垃圾回收器
- Serial(單線程——複製算法)
- ParNew(多線程——複製算法)
- Parallel Scavenge(多核多線程——複製算法)
- CMS(stop-the-world——標記清除)
- ParOld(多線程——標記清除)
- SerialOld(單線程——標記清除)
- G1(複製+標記清理,分爲不等的region,年輕老年代不再物理隔離)
- jdk 1.8(Parallel Scanvenge(新生代)+Serial Old(老年代))
- jdk 1.9(G1)
1.4 查看回收器使用
- java -XX:+PrintCommandLineFlags -version
2. jstat使用
- jstat -class vmid 類加載統計
- jstat -compiler vmid 編譯統計
- jstat -gc vmid GC查看
- jstat -gccapacity vmid 查看gc容量
- jstat -gcnew vmid 查看gc新生內存統計
- jstat -gcnewcapacity vmid 查看新生代容量
- jstat -gcold vmid 查看老年代內存統計
- jstat -gcoldcapacity vmid 查看老年代容量
- jstat -gcmetacapacity vmid 查看gc的元數據空間統計
- jstat -gcutil vmid 總結垃圾回收統計
- jstat -printcompilation vmid 編譯方法統計