JVM面試知識點梳理
程式計數器:每個執行緒執行程式指令的行號
虛擬機器棧:存放每個方法的棧幀,幀的入棧跟出棧就是方法執行的過程
本地方法棧:Native方法的棧
Java堆:儲存Java物件的地方,細分為 Eden區, From Survivor空間, ToSurvivor空間(執行緒共享)
方法區:執行緒共享,存放已經被虛擬機器載入進來的類資訊,常量、靜態變數,JIT編譯後的資料程式碼。java的class檔案首先進入的到方法區裡面去。
執行時常量池
方法區的一部分。
四大引用
強引用:只要強引用還在,引用的物件永遠不會被回收
軟引用:發生記憶體溢位之前會清除
弱引用:垃圾回收的時候會收走
虛引用:物件生命週期不會受到它影響,只是在被回收掉的時候,收到通知。
物件的存活
- 引用計數器
- 可達性演算法(堆外的引用, GC Roots)
垃圾回收演算法
- 標記清除法
- 複製演算法
- 標記整理法
- 分代收集
安全點、Minor GC、Full GC、 STW、TLAB
safePoint、安全區域 。(不操作記憶體的寫,不跟主存打交道) STW(stop the world)
eden, survior中呼叫 Minor GC,之所以沒有用STW,添加了統計老生代到 新生代資料引用的卡表(髒位)
新生代(eden + from + to)TLAB(Thread Local Allocation Buffers)由於to Survior的空間不夠,找老年代做記憶體擔保 。
當經歷過幾次 從from 到 to過程後依舊活著的物件就可以進入到 老生代中去了。
垃圾收集器
-
Serial (單執行緒,新生代,copy演算法)
-
Parallel New(多執行緒,新生代,copy演算法,時間優先)
-
Parallel Scavenge(多執行緒,新生代,copy演算法,吞吐量優先)
-
Serial Old(單執行緒,老生代, 標記清除)
-
Parallel Old(多執行緒,老生代, 標記清除)
-
CMS:垃圾收集器跟應用並行(多執行緒,老生代, 標記清除)分兩次清理,第一次清理的時候,工作執行緒跟垃圾執行緒並行,第二次STW。(Java 9 被廢除)
-
G1 (新生代 + 老生代)
類載入過程
- 載入:驗證Class檔案是否按Class的結構走的,然後載入完成之後變成記憶體的結構
- 驗證:不會等載入結束,其實交替進行的(檔案格式驗證、元資料驗證、位元組碼驗證、符號引用驗證)
- 準備:分配記憶體,虛方法動態分配的方便發表。建立符號引用(所以跟驗證是交叉的)
- 解析:(符號引用到直接引用:欄位解析、類方法解析、介面方法解析)
- 初始化 (cinit<>)
即時編譯(JIT優化)
熱點方法,迴圈熱點
C、C++屬於靜態編譯,執行時候不會。java屬於動態編譯,虛方法動態分配,激進優化等使之更徹底,但是佔用CPU。
優化方式:
-
內聯優化(省去了方法的載入,壓棧等。詭異的TR1圖)
-
逃逸分析(物件沒有被方法外引用的時候,直接到接近CPU的棧上分配儲存空間。方法僅被一個執行緒呼叫到的時候,去掉同步鎖。)
-
指令集(Compare And Sweep, Compare and Set),???
-
迴圈優化、向量優化