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 修飾的靜態變量。
類的實例化的初始化步驟
沒有父類的情況
- 類的靜態屬性
- 類的靜態代碼塊
- 類的非靜態屬性
- 類的非靜態代碼塊
- 構造方法
有父類的情況
- 父類的靜態屬性
- 父類的靜態代碼塊
- 子類的靜態屬性
- 子類的靜態代碼塊
- 父類的非靜態屬性
- 父類的非靜態代碼塊
- 父類構造方法
- 子類非靜態屬性
- 子類非靜態代碼塊
- 子類構造方法
在多次類實例化中,類靜態屬性和方法只會實例化一次,也就是執行一次
閱讀更多 互聯網Java架構 的文章