1. 程式人生 > >JVM記憶體劃分

JVM記憶體劃分

Java原始碼檔案(.java)--->經過編譯成位元組碼檔案(.class)--->然後經過JVM的各種類載入器將位元組碼檔案載入到記憶體當中
--->載入完畢後由JVM執行引擎執行。在整個程式的執行過程中,JVM會用一段空間來儲存執行期間所需要用到的資料,這段
空間被稱為執行時資料區域(Runtime data area),也就是我們所說的JVM記憶體區域,平時我們所說的JVM記憶體管理,其實就是
針對Runtime data area區域進行管理和優化。

JVM記憶體區域的劃分:
1. 堆(Heap)
在Java中堆是用來存放物件的,GC主要就是來管理回收堆記憶體,堆是被所有物件共享的,在JVM中只有一個.
2. 棧(VM Stack)
區域性變量表:指在方法中宣告的非靜態變數和方法的形參,對於基本資料型別的變數,直接儲存它的值,對於引用型別
存的是指向物件的引用.區域性變量表在編譯期間就已經確定大小了,因此在程式執行期間區域性變量表的
大小是不會改變的.
運算元棧:
程式在方法中執行的過程就是在不斷的賦值取值和計算,而這些操作都是藉助運算元棧來完成的.
指向執行時常量池的引用:
在方法執行的過程中碰到的常量,這個引用就是指向執行時常量池的.
方法的返回地址:
當一個方法執行完畢後,要返回之前呼叫它的地方,因此在棧幀中需要儲存一個方法的返回地址.
每個執行緒都會有自己的棧,互不干擾.
3. 方法區
跟堆一樣被所有執行緒共享,此區域儲存了每個類的資訊(包括類的名稱、方法資訊、欄位資訊)、靜態變數、
常量以及編譯器編譯後的程式碼等.
4. 本地方法棧
跟棧的作用和原理類似,棧是為java方法服務,而本地方法棧是為native方法服務的,在HotSpot虛擬機器中棧和
本地方法棧指的是同一塊記憶體區域.
5. 程式計數器(PC暫存器)
這塊記憶體儲存的是程式當前執行的指令的地址,當CPU需要執行指令時,需要從程式計數器中得到當前需要執行的
指令所在儲存單元的地址,然後根據得到的地址獲取到指令,在得到指令之後,程式計數器便自動加1或者
根據轉移指標得到下一條指令的地址,如此迴圈,直至執行完所有的指令.每個執行緒都會有自己獨立的程式計數器,
並且不相互影響,在JVM規範中規定,如果執行緒執行的是native方法,那麼程式計數器儲存的值是undefined.還有就是
程式計數器中記憶體的資料所佔用的空間大小不會隨著程式的執行而改變,因此對於程式計數器這塊記憶體是不會發生
OOM的.