jvm資料區域劃分
jvm資料區域劃分
jvm其實是java執行時的資料區域。具體劃分如下:
說一下各個劃分的區域的功能。
程式計數器:程式計數器是一塊較小的記憶體空間。他可以記錄當前程式執行的位置。他指向了當前執行的位元組碼
的行號。通過改變程式計數器的值可以實現分支,迴圈,跳轉,異常處理,縣城回覆等基礎的功能。每個執行緒都有
一個獨立的計數器,這個計數器屬於"執行緒私有"的記憶體區域。如果虛擬機器執行的是java方法,那麼程式計數器記錄的
是正在執行的位元組碼指令的地址。如果虛擬機器執行的是native方法(作業系統本地的方法),那麼程式計數器記錄為空。
java虛擬機器棧:java虛擬機器棧是跟執行緒的生命週期一致的,他是執行緒私有的。每開啟一個執行緒就會向記憶體申請一個
虛擬機器棧。執行緒裡的每個方法執行時都會有一個棧幀。用於儲存區域性變量表,運算元棧,動態連結,方法出口等信
息。比如在方法裡定義一個變數,會把這個變數壓到這個棧幀中,出棧之後用這個變數,然後這個變數一段時間不
用就會被回收。整個函式先出棧,執行完了也記憶體也會被回收。區域性變量表中存放了編譯器可知的基本資料型別,
int,double等。還有物件的引用,可以理解為物件變數。區域性變量表是在編譯期間確定的。執行期間不會改變區域性
變量表的大小。
java本地方法棧:java本地方法棧和虛擬機器棧相似,只不過虛擬機器棧是為Java方法服務,而本地方法棧是為本地
方法服務。與虛擬機器棧一樣,當申請的記憶體超過虛擬機器棧的允許最大深度的時候會報出StackOverFlowError棧溢位
當棧動態擴充套件之後無法擴充套件到到需要的記憶體,申請記憶體失敗的時候就會報出OutOfMemoryError記憶體溢位。
java堆:java堆是虛擬機器所管理記憶體中最大的一塊。java堆是被執行緒所共享的區域。幾乎所有物件的例項都在這裡
分配記憶體。java可能會為每個執行緒申請一個獨立的分配緩衝區(TLAB)。這些緩衝區儲存的仍然是物件例項,這樣的
目的是為了更好地管理記憶體。如果物件的例項沒有在堆中分配出空間,並且堆無法擴充套件的時候,就會報
OutOfMemoryError記憶體溢位。
方法區:方法區是被執行緒所共享的區域,方法區裡存放著編譯後加載的類資訊,常量,靜態變數等。方法區
除了可以選擇固定大小或者可擴充套件記憶體區域,儲存位置不需要連續等和堆相同的特性外,方法區還可以選擇是否
實現垃圾回收。方法去申請記憶體失敗會報出OutOfMemoryError記憶體溢位異常。
執行時常量池:常量池是存在方法區中的。當類被編譯成class檔案之後,class檔案除了記錄了類的欄位,版本號
方法,介面等,還有常量池。存放著編譯期生成的符號引用。比如一個類中有個域或者方法中的變數初始化,
String s="abcd";那麼abcd就會在編譯時期存在常量池中。變數或者域就會指向常量池中的abcd字串。常量不一定
在編譯期產生,在執行時候也能將常量放在常量池中,比如String類的intern()方法。