java虛擬機詳解

Java虛擬機示意圖

方法區(持久代)存放class信息和類的靜態方法和屬性、常量。大小由-XX:PermSize來調節堆用於存放類的實例化對象信息的 堆大小由-Xmx 和 -Xms來調節分為{Old + New={Eden,from,to}}棧存放方法執行時的局部變量、執行順序等 棧大小由Xss來調節程序計數器它的作用是當前線程所執行的字節碼的行號指示器。本地方法棧JVM採用本地方法棧來支持native方法的執行,此區域用於儲存每個native方法調用的狀態。

例子 -XX:MaxPermSize=512m -Xms256M -Xmx512M -XX:PermSize=256m

介紹幾個常用的配置選項

類加載過程

類加載機制是雙親委派機制

雙親委派機制避免了一個類被多次加載。

類裝載過程

Loading[加載]將文件系統中的Class文件載入到JVM內存(運行數據區域)Verifying[驗證]將已經讀入到內存類的二進制數據合併到虛擬機運行時環境中去。類文件結構檢查:格式符合jvm規範-語義檢查:符合java語言規範,final類沒有子類,final類型方法沒有被覆蓋字節碼驗證:確保字節碼可以安全的被java虛擬機執行.Preparing[準備]java虛擬機為類的靜態變量分配內存並賦予默認的初始值.如int分配4個字節並賦值為0,long分配8字節並賦值為0;Resolving[解析]將該類常量池中的符號引用都改變為直接引用。Initialing[初始化]初始化類的局部變量,為靜態域賦值,同時執行靜態初始化塊。使用卸載

初始化時機

主動初始化的6種方式

創建對象實例:new 對象的時候,會依法類的初始化,前提這個類沒有被初始化調用類的靜態屬性或為靜態屬性賦值調用類的靜態方法通過class 文件反射創建對象。初始化一個類的子類:使用子類的時候先初始化父類Java虛擬機啟動時被標記為啟動類的類:比如main方法所在的類

不會進行初始化的情況

在同一個類加載器下面只能初始化類一次,如果一斤初始化了就不必要初始化了。在編譯的時候能確定下來的靜態變量(編譯常量),不會對類進行初始化。比如final 修飾的靜態變量。

類的實例化的初始化步驟

沒有父類的情況

類的靜態屬性類的靜態代碼塊類的非靜態屬性類的非靜態代碼塊構造方法

有父類的情況

父類的靜態屬性父類的靜態代碼塊子類的靜態屬性子類的靜態代碼塊父類的非靜態屬性父類的非靜態代碼塊父類構造方法子類非靜態屬性子類非靜態代碼塊子類構造方法

在多次類實例化中,類靜態屬性和方法只會實例化一次,也就是執行一次