java執行時記憶體區域劃分(1)
劇情預告
Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。
列舉一下:
1.方法區
2.虛擬機器棧
3.本地方法棧
4.堆
5.程式計數器
執行時中劃分大致就是這麼5個區域。
1.程式計數器
程式計數器是一塊比較小的記憶體空間,它的作用可以看做是當前執行緒所執行的位元組碼的行號指示器。通俗來說,就是用來給當前執行緒計數當前執行到哪裡了。
1 public void test(){ 2 int a = 0; 3 a += 1; 4 int b = 1; 5 b += a; 6 }
而程式計數器就是用來控制當前執行到了哪一行位元組碼。
分支、迴圈、跳轉、異常處理、執行緒恢復等基礎功能都需要依賴這個計數器來完成。看來還是必不可少的啊。
Java中的多執行緒,是通過執行緒輪流切換並分配CPU時間來實現的,在某一時刻,一個CPU只會執行一跳執行緒中的指令,所以,每個執行緒都需要一個獨立的程式計數器,來保證各個執行緒之間互不影響,因此,這些佔用的記憶體都是執行緒私有的記憶體。
注意:如果正在執行的是Native方法,那麼這個計數器的值為空(Undefined)。
2.Java虛擬機器棧
這又是神馬?
這麼說吧,它就是一個與執行緒生命週期相同的玩意兒,因為在方法被執行的時候,都會產生一個棧幀用於儲存區域性變量表、操作棧、動態連結、方法出口等資訊。
從執行到方法被執行完的過程,也就是棧幀在虛擬機器棧中入棧到出棧的過程。
public void a(){ b(); } public b(){ c(); } public c(){ d(); } ...
每次呼叫都會產生一個棧幀,棧幀的深度是有限的,如果一直巢狀,就會溢位,產生StackOverflowError。
如果你問我什麼是棧,簡單解釋一下,這東西就是後進先出的一個結構,好比一個紙箱子,你先放進去的東西,壓在箱底,又放了東西,一直放知道放滿了之後,想拿出來,肯定是從最後放的那個開始拿出來,最先放進去的在最底下,最後才拿的出來,這個解釋清楚了吧。
所以你知道為何別人都說,棧記憶體中存放的是變數而不是實際物件了吧,說的就是這個棧。
請注意:棧這個東西是有限制的,不能無限往裡放,就像那箱子,總有放滿的時候,那時候,哼哼,你等著收到StackOverflowError異常吧!別怪人沒提醒你!
----------------------------------------------------------------------------------------------
本次節目到這裡,下集預告:
為何本地方法棧同樣是棧出身,命運卻不同?
為何堆記憶體中物件頻頻失竊,是規範的淪喪?還是虛擬機器的扭曲?
請關注下期節目《關於java的執行時資料區域劃分(下)》
轉載註明原文出處 http://blog.gaoqixhb.com/p/53db9de054fe5ed14e5d3300