一、JVM類加載機制——自定義類加載器
二、JVM——對象記憶體配置設定機制
三、JVM記憶體模型
四、JVM垃圾收集算法和垃圾收集器
五、CMS垃圾回收器——三色标記算法
六、G1垃圾收集器
七、JVM調優實戰——基本指令使用
八、JVM調優實戰——arthas使用
九、大流量電商系統JVM調優案例
對象記憶體配置設定流程圖
對象棧上配置設定
JVM通過逃逸分析,發現對象的作用域就在某個方法内,不會被外部通路,就把對象通過标量替換之後存儲在棧上。
**逃逸分析:**就是分析對象的作用域,是否能夠在一個方法範圍内;
**标量替換:**通過分析确定對象不會逃逸之後,JVM不會建立該對象,而是用該對象的成員變量等價替代該對象。
棧上配置設定依賴逃逸分析和标量替換。
package com.ysy.JVM對象建立和記憶體配置設定機制深度剖析;
/**
* @author shanyangyang
* @date 2020/7/23
* 開啟逃逸分析和标量替換
* -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+PrintGC
* 隻開啟标量替換,關閉逃逸分析
* -Xmx15m -Xms15m -XX:-DoEscapeAnalysis -XX:+EliminateAllocations -XX:+PrintGC
開啟逃逸分析,關閉标量替換
-Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+PrintGC
比較三種三種情況下的GC情況
*/
public class AlloctOnStack {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
alloc();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
private static void alloc() {
User user = new User();
user.setId(1);
user.setName("ysy");
}
}
大對象直接進入老年代
JVM參數-XX:PretenureSizeThreshold可以設定大對象的大小,如果超過設定的大小,對象直接存入老年代。
**優點:**避免大對象在年輕代和老年代之間轉換
package com.ysy.JVM對象建立和記憶體配置設定機制深度剖析;
/**
* @author shanyangyang
* @date 2020/7/23
* -XX:+PrintGCDetails
*/
public class GCTest {
public static void main(String[] args) {
byte[] allocation1, allocation2, allocation3, allocation4, allocation5;
allocation1 = new byte[2000 * 1024];
allocation2 = new byte[10000 * 1024];
allocation3 = new byte[8000 * 1024];
allocation4 = new byte[8000 * 1024];
allocation5 = new byte[3500 * 1025];
}
}
TLAB 本地線程配置設定緩存
解決配置設定記憶體的并發問題;
每個線程在java堆中預先配置設定一小塊記憶體,通過-XX:+UseTLAB設定。
AGE 對象達到一定年齡會進入老年代
對象第一進入survivor區域,年齡是1歲,然後每經過一次minorGC,年齡增加1歲。可以通過參數-XX:MaxTenuringThreshold來設定,預設15歲,CMS預設6歲。
對象動态年齡判斷
目前Survivor區域中的一批對象的總大小大于Suvivor區域大小的50%。
年齡1+年齡2+年齡3+…+年齡n>50%;
則把年齡大于等于N的對象轉移到老年代。
老年代空間擔保機制
finalize()方法
1、第一次标記并進行一次篩選。
篩選的條件是此對象是否有必要執行finalize()方法;
當對象沒有覆寫這個方法時,直接回收
2、如果對象覆寫了finalize()方法;對象在該方法内部重新和GCROOT建立起連接配接沒,就可以拯救自己。
注意:該方法隻會執行一次,隻有一次拯救自己的機會。