【JVM虛擬機】類的加載,連接和初始化

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
	//默認是把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 : 配置參數,可以顯示類的加載過程
TraceClassLoading
-XX:+TraceClassUnloading : 配置參數,可以顯示類的卸載的過程

參數形式的解析:
-XX :規定的
+:說明是開啓的參數
-:說明是關閉的參數

助記符

  1. 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

在這裏插入圖片描述

  1. bipush 基礎類型(int) -128~127
    通過bipush指令把常量壓到棧頂
    在這裏插入圖片描述

  2. sipush 基礎類型(int) -32768~32767
    通過sipush指令把常量壓到棧頂
    在這裏插入圖片描述

  3. ldc 基礎類型(int) -2147483648~2147483647
    通過ldc指令把常量壓到棧頂

截圖中看到,超過這個值就已經報錯了
在這裏插入圖片描述

  1. getstatic static關鍵字
    在這裏插入圖片描述
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章