JVM結構體系
jvm由`類加載器子系統`、`運行時數據區`(內存空間)、`執行引擎`及`本地方法接口`等組成
`運行時數據區:`由方法區、堆、java 棧、PC寄存器、本地方法棧組成
在內存空間中方法區和堆是所有java線程共享
的,而java棧、本地方法棧、PC寄存器則有每個線程私有
程序計數器(program counter register)
它是當前線程所執行的字節碼的行號指示器
字節碼解釋器通過改變程序計數器的值來選擇下一條需要執行的字節碼指令,分支、跳轉、循環等基礎功能都需要依賴它來實現,所以程序計數器是線程私有的,各線程間的計數器互不影響
當線程在執行一個java方法時(非本地方法),該計數器記錄的是正在執行的虛擬機字節碼指令的地址,當線程在執行的是native方法時,該計數器的值為空。唯一在java虛擬機規范中沒有OOM的區域
Java虛擬機棧(java stacks)
線程私有,保證線程安全,生命周期與線程相同
java棧由棧幀組成,每個方法被執行的時候都會同時創建一個棧幀,調用方法時壓入棧幀,方法返回時彈出棧幀并拋棄
先進后出
對于執行引擎來說,活動線程中只有棧頂的棧幀是有效的,執行引擎所運行的所有字節碼指令都只針對當前棧幀進行操作
java棧的主要任務是儲存方法參數、局部變量、中間運算結果,并且提供部分其他模塊工作需要的數據
在編譯程序代碼時,棧幀中需要多大的局部變量表、多深的操作數棧都已經完全確定來,并且寫入了方法表的code屬性之中
所以程序運行期變量數據不會影響棧幀內存大小,僅僅取決于具體的虛擬機實現。
在java虛擬機規范中,棧會拋出2種異常情況
- 1、如果
線程請求的棧
深度大于
虛擬機所允許的深度,將拋出StackOverFlowerError
異常 - 2、如果虛擬機在動態擴展棧時
無法申請到足夠的內存空間
,則拋出OutOfMemoryError
異常
本地方法棧(native method stacks)
與java棧作用類似,java棧為虛擬機執行java方法服務,本地方法棧則為使用到的本地操作系統(native)方法服務
Java堆(Heap)
堆
是所有線程
共享的一塊內存區域。幾乎所有的對象實例
和數組
都在這類分配內存
java堆可以處理在物理上不連續的內存空間 中 ,只要是邏輯上是連續就可以
如果在堆中沒有內存可分配時,并且堆也無法擴展時,將會拋出OutOfMemoryError
異常
方法區(method area)
各個線程共享的內存區域
用于存儲已經被虛擬機加載的類信息、常量、靜態常量 ,即時編譯器編譯后的代碼等數據。和java heap一樣不需要連續的內存,可以選擇固定大小或可擴展
虛擬機規范允許該區域可以選擇不實現垃圾回收
根據java虛擬機規范,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError
異常
類加載機制
類的整個生命周期包括:加載、驗證、準備、解析、初始化、使用和卸載七個階段
類加載的過程包括了:加載->驗證->準備 ->解析-> 初始化
按順序開始
,而不是按順序進行
或完成
,通常都是互相交叉
地混合進行,在一個階段執行的過程中調用
或激活
另一個階段