標籤:模型 rom 除了 回收 卸載 runtime werror output double
Java記憶體地區運行時資料區域
程式計數器(Program Counter Register)
- 較小的記憶體空間,是當前線程執行的位元組碼的行號的指標。位元組碼解譯器通過改變計數器的值來擷取下一條位元組碼指令,分支、迴圈、跳轉、異常處理、線程恢複都靠它完成.
- 每個線程都有自己的一個計數器,線程之間計數器互不影響.
- 執行Native方法時,計數器不起作用,值為空白(Undefined)。
- 此地區是唯一沒有規定OOM的地區.
Java虛擬機器棧 Java Virtual Machine Stack
- 歸屬線程所有,生命週期與歸屬的線程相同。
- 虛擬機器棧描述的是Java方法執行的記憶體模型:
- 方法執行時會建立棧幀(Stack Frame)儲存局部變數表、運算元棧、動態連結、方法出口等.
- 方法的調用到執行完成的過程,對應其棧幀從虛擬機器棧中入棧到出棧的過程.
- 局部變數表存放編譯器可知的基礎資料型別 (Elementary Data Type)、對象引用;long、double因為長度為64bit,會佔用兩個Slot,其他則佔用一個,由此可知局部變數表的記憶體空間在編譯期就完成了分配,方法運行時不改變其大小。
- 虛擬機器棧中規定的兩種異常情況:
- StackOverflowError:線程請求的棧深度大於虛擬機器所允許的深度.
- OutOfMemoryError:虛擬機器棧動態擴充記憶體時,無法申請到足夠的記憶體.
本地方法棧 Native Method Stack
- 類似於虛擬機器棧,區別是虛擬機器棧為虛擬機器執行Java方法服務,而本地方法棧為Native方法工作;Native方法指Java調用的C/C++語言的函數.
- 本地方法棧地區也會拋出StackOverFlowError & OutOfMemoryError異常。
Java堆 Java Heap
方法區 Method Area
- 所有線程共用,別名No-Heap(非堆)用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料。也叫Permanent Generation(永久代);之所以名為永久代,是因為HotSpot將GC從堆延伸至了方法區。(對於其他虛擬機器IBM J9等來說是不存在永久代的概念的)
- 與Java堆一樣,是各個線程共用的記憶體地區,它用於儲存 已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料。
- 並非被稱為永久代,其中的資料就永久了,當類型卸載、常量池回收時也會發生GC,但是比較少見。
- 當此區無法分配新記憶體時,拋出OOM異常。
運行時常量池 Runtime Constant Pool
- 屬於方法區的一部分,Class檔案中除了有類的版本、欄位、方法、介面等描述資訊外,還有一項資訊是常量池(Constant Pool Table),用於存放編譯期產生的各種字面量和符號引用,這部分內容將在類載入後進入方法區的運行時常量池中存放。
- 無法申請到記憶體時,拋出OOM異常.
直接記憶體
- 直接記憶體不是JVM運行時的一部分,但是Java可以通過NIO(New Input/Output),引入Channel和Buffer的I/O方式,它可以用native方法申請堆外記憶體,然後通過JVM堆中的DirectByteBuffer對象操作這塊記憶體,此時申請記憶體是通過Unsafe.allocateMemory方法實現的.
對象訪問
- 控制代碼訪問方式:Java堆中分配一塊記憶體作為控制代碼池,reference中儲存物件的控制代碼地址,控制代碼中則包含執行個體資料指標和類型資料指標;此方式的好處在於控制代碼地址穩定,對象變動時,只需修改控制代碼,而reference不需改動.
- 直接指標訪問方式:Java堆對象中存放訪問類型資料資訊,reference直接儲存物件地址;這種做法的好處是速度快,節省了一次指標定位的開銷.
Java虛擬機器