Java虛擬機在執(zhí)行Java程序的過程中會把他所管理的內(nèi)存劃分為幾個數(shù)據(jù)區(qū)域。

程序計數(shù)器(Program Counter Register)
程序計數(shù)器: 當前線程所執(zhí)行的字節(jié)碼的行號指示器,用于記錄當前線程下一條需要執(zhí)行的字節(jié)碼指令
為了線程切換后能恢復(fù)正確的執(zhí)行位置,每條線程都有一個獨立的程序計數(shù)器
線程私有內(nèi)存(各條線程間的程序計數(shù)器互不影響,獨立存儲)
若線程執(zhí)行的是Java方法,計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址
若線程執(zhí)行的是Native方法,計數(shù)器值為空(Undefined)
Java虛擬機棧(Java Virtual Machine Stacks)
線程私有,生命周期和線程相同
利用棧幀(Stack Frame)存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,每個方法的調(diào)用直至完成都代表一個棧幀在虛擬機棧中出棧入棧的過程
-
StackOverflowError異常: 當線程請求的棧深度大于虛擬機所允許的深度
OutOfMemoryError異常:虛擬機棧擴展時無法申請到足夠的內(nèi)存
局部變量表
存放了編譯期可知的各種基本數(shù)據(jù)類型(int、btye等)、對象的引用和returnAddress類型(指向了一條字節(jié)碼指令的地址)
其中64位長度的long和double占用2個局部變量空間(Slot),其余占一個
局部變量表所需的內(nèi)存空間在編譯期完成分配。當進入一個方法時,該方法在棧中分配的局部變量空間是完全確定的,在方法運行期間局部變量表不會改變大小
本地方法棧
與虛擬機棧的區(qū)別 :虛擬機棧為虛擬機執(zhí)行java代碼服務(wù),本地方法棧為虛擬機使用到的Native方法服務(wù)
StackOverflowError和OutOfMemoryError
Java堆(Java Heap)
被所有線程共享的內(nèi)存區(qū)域
用于存放對象實例
java堆可以是物理上不連續(xù)的內(nèi)存空間,實現(xiàn)時既可以固定大小,也可以可擴展
OutOfMemoryError
方法區(qū)(Method Area)
-
線程共享,用于存儲已經(jīng)被虛擬機加載的類信息、常量、靜態(tài)變量、編譯后的代碼等數(shù)據(jù)
運行時常量池
方法區(qū)的一部分。Class文件中的常量池,用于存放編譯器生成的字面量和符號引用,這部分將在類加載后存入運行時常量池
運行時常量池和Class文件常量池的區(qū)別:運行時常量池具備動態(tài)性(并不一定只有編譯器才會產(chǎn)生常量,代碼運行期間產(chǎn)生的常量就可以放入運行時常量池,比如:String類的intern( )方法)