1. Java 文件執行過程
2. 運行數據區域
Runtime Data Areas:當運行一個JVM示例時,系統將分配給它一塊內存區域(這塊內存區域的大小可以設置的),這一內存區域由JVM自己來管理。
運行數據區域可以划分為6大塊:
a) Java棧
b) 程序計數寄存器(PC寄存器)
c) 本地方法棧(Native Method Stack)
d) Java堆
e) 方法區域
f) 運行常量池(Runtime Constant Pool)
2.1 PC寄存器
每一個線程都擁有一個PC計數器,當線程啟動(start)時,PC計數器被創建,這個計數器存放當前正在被執行的字節碼指令(JVM指令)的地址。
2.2 Java棧
Java棧也是每個線程單獨擁有,線程啟動時創建。這個棧中存放着一系列的棧幀(Stack Frame),JVM只能進行壓入(Push)和彈出(Pop)棧幀這兩種操作。每當調用一個方法時,JVM就往棧里壓入一個棧幀,方法結束返回時彈出棧幀。如果方法執行時出現異常,可以調用printStackTrace等方法來查看棧的情況。棧的示意圖如下:
2.3 本地方法棧
當程序通過JNI(Java Native Interface)調用本地方法(如C或者C++代碼)時,就根據本地方法的語言類型建立相應的棧。
2.4 方法區域
方法區域是一個JVM實例中的所有線程共享的,當啟動一個JVM實例時,方法區域被創建。它用於存運行放常量池、有關域和方法的信息、靜態變量、類和方法的字節碼。不同的JVM實現方式在實現方法區域的時候會有所區別。Oracle的HotSpot稱之為永久區域(Permanent Area)或者永久代(Permanent Generation)。
2.5 運行常量池
這個區域存放類和接口的常量,除此之外,它還存放方法和域的所有引用。當一個方法或者域被引用的時候,JVM就通過運行常量池中的這些引用來查找方法和域在內存中的的實際地址。
2.6 堆(Heap)
堆中存放的是程序創建的對象或者實例。這個區域對JVM的性能影響很大。垃圾回收機制處理的正是這一塊內存區域。所以,類加載器加載其實就是根據編譯后的Class文件,將java字節碼載入JVM內存,並完成對運行數據處於的初始化工作,供執行引擎執行。
3. 執行引擎(Execution Engine)
類加載器將字節碼載入內存之后,執行引擎以Java 字節碼指令為但願,讀取Java字節碼。問題是,現在的java字節碼機器是讀不懂的,因此還必須想辦法將字節碼轉化成平台相關的機器碼。這個過程可以由解釋器來執行,也可以有即時編譯器(JIT Compiler)來完成。
參考資料: