共计 1022 个字符,预计需要花费 3 分钟才能阅读完成。
本篇記錄下學習 JVM 的心得,主要參考 Youtube 上的相關影片,文後會附上連結,用於筆記。
JVM 加載過程 (加載 -> 鏈接 -> 初始化)
加載
把位元組碼 (Bytecode) 内容加载到記憶體中,Bytecode 本質就是是位元組陣列也可以是網路上伺服器發來的或者是 Jar 包,來源很多。
鏈接
位元組碼被類載入器合併到 JVM 的運行狀態之中,可細分為以下環節【驗證 -> 準備 -> 解析】
初始化
方法區形成執行時二進位制資料結構,時在堆裡面也會生成一個代表這個 class 的物件
- 類構造器 <clinit>()方法的過程,該方法由編譯器自動收集類的有類變數的賦值動作和靜態語句塊 (static) 中的語句合併產生
- 當初始化一個類的時候,如果發現其父類還沒有進行初始化,則需要先將其父類初始化
- 虛擬機器保證一個類的 <clinit>()方法在多執行緒環境中被正確加鎖和同步
- 當訪問一個 Java 類的靜態域時,只有真正聲明這個域的類才會被初始化
<clinit> 類的初始化方法
<init> 類的建構函式,沒有寫建構函式,虛擬機器器預設插入,無參數的建構函式
測試 Demo 程式碼
新增一個專案,運行下述程式碼
public class Main {public static void main(String[] args) {A a = new A();
System.out.println(A.width);
}
}
class A {
public static int width = 100;
static {System.out.println("靜態初始化 A");
width = 300;
}
public A() {System.out.println("創建 A 類對象");
}
}
得到結果如下
靜態初始化 A
創建 A 類對象
300
分析運行原理
- 在方法區加載 main 類的靜態變量、靜態方法、常量池、類的程式碼
- 在堆裡生成 java.lang.Class 物件代表 main 類
- 在方法區加載 A 類的靜態變量、靜態方法、常量池、類的程式碼
- 在堆裡生成 java.lang.Class 物件代表 A 類
- 執行 main 類裡面的 main 方法並在棧裡面生成棧桢,裡面置入方法的基本變量以及引用變量,本例為引用變量 a
- 執行 A 類裡面的構造函數在棧裡面生成棧桢
- 在堆裡面生成 A 類物件
- 將 A 類物件的地址指給 main 方法裡面的 a 引用變量
正文完