jdk版本:Java HotSpot™ 64-Bit Server VM (build 25.131-b11, mixed mode)
JVM虛擬機的學習可能更偏向於理論,但是當你理解了JVM虛擬機後,你將會寫出更好的代碼,性能更好的代碼。
今天先介紹JVM對類的處理,總共分爲加載
,連接
,初始化
,下面我們慢慢介紹
首先,我們先看java虛擬機的退出情況
java的虛擬機和程序的生命週期
在如下的情況下,java虛擬機會結束生命週期
- 執行了System.exit()方法
- 程序正常結束
- 程序在執行中遇到異常或者錯誤而異常終止
- 由於操作系統出現錯誤,導致java虛擬機退出
下面我們來詳細瞭解下java虛擬機中類的加載過程
加載
描述:
類的加載是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法內,然後在內存中和攢國家一個java.lang.Class
對象,用來封裝類在方法區內的數據結構
可以多種類型文件:
- 從本地系統中直接加載
- 通過網絡下載.class文件
- 從zip,jar等歸檔文件中加載.class文件
- 從數據庫中提取.class文件
- 將java源代碼編譯成.class二進制文件
連接
- 驗證 :確保被加載類的正確性
- 準備 :爲類的
靜態變量
分配內存,並把它初始化爲默認值
- java中一些變量有一些默認值:
- int = 0
- java中一些變量有一些默認值:
//默認是把i賦值爲0
public final static int i = 0;
- 解析 :把類中的符號引用轉換成直接引用
- 符號表示:間接引用
- 直接引用:直接指針指向某個類的方法
初始化
把類的靜態變量賦值爲正確的初始值
//默認是把i賦值爲0
public final static int i = 2;
注意:所有的JAVA虛擬機實現必須在每個類或者接口被java程序首次主動使用
時纔會初始化他們
使用
正常使用類 ,比如 new String();
java程序對類的使用分爲2種
- 主動使用 (7種)
- 創建類的實例
public class Test1 { public static void main(String[] args) { //這裏創建實例 MyParent myParent = new MyParent(); System.out.println(myParent); } public static class MyParent {} }
- 訪問某個類或者接口的
靜態變量
,或者對該靜態變量
進行賦值 這裏其實並不會去加載MyParent,這裏留了個坑哦???,詳細請看下一章
public class Test1 { public static void main(String[] args) { //調用靜態變量 System.out.println(MyParent.str); } public static class MyParent { public static final String str = "123"; public MyParent() { System.out.println("myParent init"); } } }
- 調用類的靜態方法
- 反射
- 初始化一個類的子類
public class Test1 { public static void main(String[] args) { MyChild myChild = new MyChild(); } public static class MyParent { public MyParent() { System.out.println("myParent init"); } } public static class MyChild extends MyParent{ public MyChild() { System.out.println("MyChild init"); } } }
- java虛擬機啓動時,被標記爲啓動類的類 如:Java Test
- Jdk1.7 開始提供的動態語言支持
- 被動使用
除了主動使用,其他都是被動使用
卸載
把加載到java虛擬機中的class類刪除掉
下面3種情況會導致類的卸載
-
類加載器沒有被引用
-
類對象沒有被引用
-
沒有該類的實例對象存在
擴充:
JVM的參數介紹
-XX:+TraceClassLoading
: 配置參數,可以顯示類的加載過程
-XX:+TraceClassUnloading
: 配置參數,可以顯示類的卸載的過程
參數形式的解析:
-XX :規定的
+:說明是開啓的參數
-:說明是關閉的參數
助記符
iconst_*
基礎類型(int) -1~5
通過iconst_*指令把常量壓到棧頂
指令 | 值 |
---|---|
iconst_m1 | -1 |
iconst_0 | 0 |
iconst_1 | 1 |
iconst_2 | 2 |
iconst_3 | 3 |
iconst_4 | 4 |
iconst_5 | 5 |
-
bipush
基礎類型(int) -128~127
通過bipush指令把常量壓到棧頂
-
sipush
基礎類型(int) -32768~32767
通過sipush指令把常量壓到棧頂
-
ldc
基礎類型(int) -2147483648~2147483647
通過ldc指令把常量壓到棧頂
截圖中看到,超過這個值就已經報錯了
getstatic
static關鍵字