1. 程式人生 > >Java虛擬機器(JVM原始碼):JDK10對Java虛擬機器執行時資料區的劃分(詳細圖解)

Java虛擬機器(JVM原始碼):JDK10對Java虛擬機器執行時資料區的劃分(詳細圖解)

Java虛擬機器執行時資料區

為什麼要研究這個,因為JDK都已經發布到10了,必須要更新自己對Java虛擬機器新的認識。

一、執行時資料區的劃分

1.1 官方劃分

關於JDK10對執行時資料區的劃分,在官方文件說的非常清楚。
學習技術,一定要學會看第一手資料。

Java虛擬機器規範基於JDK10地址

1.2.根據文件繪資料區圖

注意:
執行緒共享:堆、方法區
執行緒私有:棧、本地方法棧、程式計數器

這裡寫圖片描述

1.3 執行時資料區

Java虛擬機器定義了在程式執行期間使用的各種執行時資料區域。其中一些資料區域是在Java虛擬機器啟動時建立的,僅在Java虛擬機器退出時銷燬。其他資料區域是每個執行緒。執行緒資料區域是線上程退出時建立和銷燬執行緒時建立的。

二、Java虛擬機器規範(基於JDK10的解釋)

2.1 The pc Register

程式計數器(暫存器)
Java虛擬機器可以同時支援許多執行執行緒(JLS§17)。每個Java虛擬機器執行緒都有自己的 pc(程式計數器)暫存器。在任何時候,每個Java虛擬機器執行緒都在執行單個方法的程式碼,即該執行緒的當前方法。如果該方法不是 native,則pc暫存器包含當前正在執行的Java虛擬機器指令的地址。如果執行緒當前正在執行該方法native,則Java虛擬機器pc 暫存器的值未定義。Java虛擬機器pcregister足夠寬,可以returnAddress在特定平臺上儲存或指向本機指標。

2.2 Java Virtual Machine Stacks

Java虛擬機器棧
每個Java虛擬機器執行緒都有一個私有Java虛擬機器棧,與執行緒同時建立。Java虛擬機器棧儲存幀(第2.6節)。Java虛擬機器棧類似於傳統語言的棧,例如C:它儲存區域性變數和部分結果,並在方法呼叫和返回中起作用。由於除了推送和彈出幀之外,永遠不會直接操作Java虛擬機器棧,因此可以對堆進行堆分配。Java虛擬機器棧的記憶體不需要是連續的。

在第一版中的Java ®虛擬機器規範,Java虛擬機器堆被稱為Java堆疊。

此規範允許Java虛擬機器棧具有固定大小或根據計算的需要動態擴充套件和收縮。如果Java虛擬機器棧具有固定大小,則可以在建立該棧時獨立選擇每個Java虛擬機器堆疊的大小。

Java虛擬機器實現可以為程式設計師或使用者提供對Java虛擬機器棧的初始大小的控制,以及在動態擴充套件或收縮Java虛擬機器棧的情況下,控制最大和最小大小。

以下異常條件與Java虛擬機器棧相關聯:

  • 如果執行緒中的計算需要比允許的更大的Java虛擬機器棧,則Java虛擬機器會丟擲一個StackOverflowError。
  • 如果可以動態擴充套件Java虛擬機器棧,並且嘗試進行擴充套件但可以使記憶體不足以實現擴充套件,或者可以使記憶體不足以為新執行緒建立初始Java虛擬機器棧,則可以使用Java虛擬機器堆疊機器丟擲一個OutOfMemoryError。

2.3 Heap


Java虛擬機器具有在所有Java虛擬機器執行緒之間共享的堆。堆是執行時資料區,從中分配所有類例項和陣列的記憶體。

堆是在虛擬機器啟動時建立的。物件的堆儲存由自動儲存管理系統(稱為垃圾收集器)回收 ; 物件永遠不會被顯式釋放。Java虛擬機器假設沒有特定型別的自動儲存管理系統,可以根據實現者的系統要求選擇儲存管理技術。堆可以是固定大小的,或者可以根據計算的需要進行擴充套件,如果不需要更大的堆,則可以收縮。堆的記憶體不需要是連續的。

Java虛擬機器實現可以為程式設計師或使用者提供對堆的初始大小的控制,以及如果可以動態擴充套件或收縮堆,則控制最大和最小堆大小。

以下異常情況與堆相關聯:

  • 如果計算需要的堆量超過自動儲存管理系統可用的堆,則Java虛擬機器會丟擲一個 OutOfMemoryError。

2.4 Method Area

方法區
Java虛擬機器具有在所有Java虛擬機器執行緒之間共享的方法區域。方法區域類似於傳統語言的編譯程式碼的儲存區域或類似於作業系統程序中的“文字”段。它儲存每類結構,例如執行時常量池,欄位和方法資料,以及方法和建構函式的程式碼,包括類和介面初始化以及例項初始化(第2.9節)中使用的特殊方法。

方法區域是在虛擬機器啟動時建立的。雖然方法區域在邏輯上是堆的一部分,但是簡單的實現可能選擇不垃圾收集或壓縮它。此規範不強制方法區域的位置或用於管理編譯程式碼的策略。方法區域可以是固定大小的,或者可以根據計算的需要進行擴充套件,並且如果不需要更大的方法區域,則可以縮小方法區域。方法區域的記憶體不需要是連續的。

Java虛擬機器實現可以為程式設計師或使用者提供對方法區域的初始大小的控制,以及在變大小方法區域的情況下,控制最大和最小方法區域大小。

以下異常條件與方法區域相關聯:

  • 如果方法區域中的記憶體無法滿足分配請求,則Java虛擬機器會丟擲OutOfMemoryError。

2.5 Run-Time Constant Pool

執行時常量池
甲執行時間常數池是的每個類或每個介面的執行時表示constant_pool在表class檔案(§4.4)。它包含幾種常量,從編譯時已知的數字文字到必須在執行時解析的方法和欄位引用。執行時常量池提供類似於傳統程式語言的符號表的功能,儘管它包含比典型符號表更寬範圍的資料。

每個執行時常量池都是從Java虛擬機器的方法區域(第2.5.4節)中分配的。當Java虛擬機器建立類或介面(第5.3節)時,將構造類或介面的執行時常量池。

以下異常條件與類或介面的執行時常量池的構造相關聯:

  • 在建立類或介面時,如果執行時常量池的構造需要的記憶體比Java虛擬機器的方法區域中可用的記憶體多,則Java虛擬機器會丟擲一個OutOfMemoryError。

2.6 Native Method Stacks

本地方法棧
Java虛擬機器的實現可以使用傳統的堆疊,俗稱“C堆疊”,以支援native方法(用Java程式語言以外的語言編寫的方法)。
本機方法堆疊也可以用於以諸如C語言的Java虛擬機器的指令集的直譯器的實現來使用。無法載入native 方法並且本身不依賴於傳統堆疊的Java虛擬機器實現不需要提供本機方法堆疊。 。如果提供,則通常在建立每個執行緒時為每個執行緒分配本機方法堆疊。

此規範允許本機方法堆疊具有固定大小或根據計算的需要動態擴充套件和收縮。如果本機方法堆疊具有固定大小,則可以在建立該堆疊時獨立地選擇每個本機方法堆疊的大小。

Java虛擬機器實現可以為程式設計師或使用者提供對本機方法堆疊的初始大小的控制,以及在不同大小的本機方法堆疊的情況下,控制最大和最小方法堆疊大小。

以下異常條件與本機方法堆疊相關聯:

  • 如果執行緒中的計算需要比允許的更大的本機方法堆疊,則Java虛擬機器會丟擲一個StackOverflowError。
  • 如果可以動態擴充套件本機方法堆疊並嘗試進行本機方法堆疊擴充套件,但可以使記憶體不足,或者如果沒有足夠的記憶體可用於為新執行緒建立初始本機方法堆疊,則Java虛擬機器會丟擲OutOfMemoryError。

好啦,關於Java虛擬機器的記憶體劃分,先聊這麼多。
光知道肯定還是不夠的。需要多加實踐和理解。