本文是對JVM執行一個Class文件的過程的一個總結。比如,現在我有2個類:
1:Class Lava {
?? private int speed = 5;
?? void flow() {}
}
2:??? Class Volcano {
?? public static void main(String [] args) {
??? Lava lava =? new Lava ();
??? lava.flow()
}
}
下面就是JVM的某個實現執行Class文件的一個過程:
1:JVM找到并讀入相應的Class文件 :Volcano.class,然后把導入的二進制數據中提取的類型信息保存到方法區(方法區:保存類型信息的運行時數據區,也就是JVM內存管理體系結構的一個組成)
2:執行保存在方法區的字節碼 (執行main()方法的字節碼,)在執行時,持有指向Volcano類常量池的一個指針 (常量池:就是一個符號引用 如:Lava lava = new Lava()這句中的Lava就是一個符號引用)
3:JVM只在需要時才裝載類(動態連接) 。JVM使用常量池指針找到第一項,發現是"Lava"字符串,檢查方法區,發現Lava類并未被裝載。
4:開始裝載Volcano.class,同樣,把讀入的二進制數據中的類型信息放到方法區。
5:JVM用一個直接指向方法區Lava類數據的指針來替換常量池的第一項,也就是原先的“Lava”字符串。 這個過程就是所謂的:“常量池解析”---符號引用替換為直接引用。
6:JVM準備為新的Lava對象分配內存。分配對象當然需要類型信息,此時,用剛才替換的那個指針,也就是替換“Lava”字符串的那個指針(此時,這個指針指向方法區Lava類的數據)來訪問Lava的類型信息(這個信息剛放到方法區)。找出其中記錄的這樣一個信息:需要分配多少內存。
7:確定內存要多大以后,在堆上分配內存,并初始化變量,包括超類的變量()。
8:把新生成的Lava對象引用壓到Java棧中。到此,完成Lava lava = new Lava(); speed初始化為0。
9:通過此時生成的Lava引用,把speed 初始化為正確的值 :5
10: 通過這個引用調用Flow()。
以上為我以一個例子來說明JVM 的一個實現執行Class的流程,歡迎大家閱讀和提出意見.