JVM運行時數據區(Run-Time Data Areas)

JVM運行時數據區(Run-Time Data Areas)

    今天在網上搜索了關於JVM運行時數據區的介紹,發現很多人對於這個基礎知識的理解偏差,簡單列舉幾個比如
有人認爲方法區在jdk8被移除了;

之後查閱了jdk8的JVM架構介紹,jdk11的JVM架構介紹 確定了一些事兒,先貼一張圖,根據官方介紹自己畫的.
在這裏插入圖片描述

pc寄存器(The pc Register)

  1. pc代表program counter,Java虛擬機可以支持多線程同時執行。
  2. 每個Java虛擬機線程都有自己的 pc(程序計數器)寄存器。
  3. 在任何時候,每個Java虛擬機線程都在執行單個方法的代碼,即該線程的當前方法。
  4. 如果該方法不是native(本機底層)的,則pc寄存器包含當前正在執行的Java虛擬機指令的地址。如果線程當前執行的方法是native(本機底層)的,則Java虛擬機的pc寄存器的值是未定義的。
  5. Java虛擬機pc寄存器足夠大,可以裝下在特定平臺上的返回地址或native(本機底層)指針。

Java虛擬機堆棧(Java Virtual Machine Stacks)

  1. 每個Java虛擬機線程都有一個私有Java虛擬機堆棧,與線程同時創建。
  2. Java虛擬機堆棧存儲棧幀。
  3. Java虛擬機堆棧類似於傳統語言的堆棧,例如C:它保存局部變量和部分結果,並在方法調用和返回中起作用。由於除了進棧和出棧之外,永遠不會直接操作Java虛擬機堆棧,因此可以對棧幀進行堆分配。Java虛擬機堆棧的內存不需要是連續的。

在第一版中的Java ®虛擬機規範,Java虛擬機堆被稱爲Java堆棧。

  1. 該規範允許Java虛擬機堆棧具有固定的大小,或者根據計算的需要動態擴展和收縮。
  2. 如果Java虛擬機堆棧的大小是固定的,則可以在創建該堆棧時獨立選擇每個Java虛擬機堆棧的大小。

Java虛擬機實現可以爲程序員或用戶提供對Java虛擬機堆棧初始大小的控制,在動態擴展或收縮Java虛擬機堆棧的情況下,還可以提供對最大和最小大小的控制

注意:以下異常與Java虛擬機堆棧有關:

如果線程中的操作或者計算需要更大的Java虛擬機堆棧,而需要的比提供的大,Java虛擬機將拋出StackOverflowError。

如果Java虛擬機棧允許動態地擴展,然後試圖擴展時可以可用內存不足,則Java虛擬機將拋出OutOfMemoryError錯誤;如果沒有足夠的內存可用來爲新線程創建初始Java虛擬機堆棧,則Java虛擬機將拋出OutOfMemoryError。

堆(Heap)

  1. 所有對象及其對應的實例變量和數組都存儲在堆內存中;
  2. 這個內存區域是在JVM啓動時創建的;
  3. 每個JVM只有一個堆區域跨多個線程共享,因爲存儲在該區域中的數據不是線程安全的;
  4. 如果存儲在堆內存中的對象沒有引用,則由垃圾回收器GC回收該對象的內存, 此區域中的對象從未顯式釋放;
  5. 堆的大小可以是固定的,也可以根據計算的需要進行擴展,如果不需要更大的堆,則可以收縮.
    以下異常情況與該區域有關:

Java虛擬機可以爲程序員或用戶提供堆初始大小的控制,如果堆可以動態擴展或收縮,還可以控制堆的最大和最小大小

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

如果需要更多的堆內存,而JVM提供的堆內存太小,Java虛擬機將拋出OutOfMemoryError。

方法區(Method Area)

  1. 保存每個.class文件的類級數據,如元數據、運行時常量池、靜態變量、字段和方法數據,以及方法和構造函數的代碼,包括類和實例初始化以及接口初始化中使用的特殊方法等。
  2. 方法區域類似於傳統語言的編譯代碼的存儲區域或類似於操作系統進程中的“文本”段。
  3. 每個JVM只有一個方法區域,並且在所有類之間共享。
  4. 分配給這個區域的內存默認情況下是由JVM分配的,或者可以根據計算需要增加。
  5. 方法區域是在虛擬機啓動時創建的。
  6. 雖然方法區域在邏輯上是堆的一部分,但是對於一些簡單的實現JVM可能選擇不去垃圾回收或壓縮它們。
  7. 方法區域可以是固定大小的,或者可以根據操作的需要進行擴展,並且如果不需要更大的方法區域時,則可以自動縮小方法區域。
  8. 方法區域的內存不需要是連續的。

Java虛擬機實現可以提供程序員或用戶對方法區域的初始大小的控制,以及在變大小方法區域的情況下,控制最大和最小方法區域大小。

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

如果方法區域中的內存無法滿足分配請求,則Java虛擬機會拋出一個OutOfMemoryError。

運行時常量池(Run-Time Constant Pool)

  1. 運行時常量池是類文件中constant_pool表的每個類或每個接口的運行時表示;
  2. 包括很多類型的常量,從編譯時已知的數值常量到必須在運行時解析的方法和字段引用。
  3. 運行時常量池的功能類似於傳統編程語言的符號表,儘管它包含的數據範圍比典型符號表更廣。
  4. 每個運行時常量池都是從Java虛擬機的方法區域中分配的。
  5. 當Java虛擬機創建類或接口時,將創建類或接口的運行時常量池。

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

在創建類或接口時,如果運行時常量池的構造需要的內存比Java虛擬機的方法區域中可用的內存多,則Java虛擬機會拋出一個OutOfMemoryError。

本地方法堆棧(Native Method Stacks)

  1. Java虛擬機的實現可以使用傳統堆棧(俗稱“C堆棧”)來支持本機方法(用Java編程語言以外的語言編寫的方法)。
  2. Java虛擬機指令集解釋器的實現也可以使用本機方法堆棧,解釋器使用的語言是C語言.無法加載本機方法且本身不依賴於傳統堆棧的Java虛擬機實現不需要提供本機方法堆棧。
  3. 如果提供了本機方法堆棧,則通常在創建每個線程時爲每個線程分配本機方法堆棧。
  4. 該規範允許本機方法堆棧具有固定的大小,或者根據計算的需要動態擴展和收縮。如果本地方法堆棧的大小是固定的,則可以在創建該堆棧時獨立選擇每個本機方法堆棧的大小。

Java虛擬機實現可以爲程序員或用戶提供對原生方法堆棧初始大小的控制,以及在可變大小的原生方法堆棧的情況下,提供對最大和最小方法堆棧大小的控制。

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

如果線程中的計算需要比允許的更大的本機方法堆棧,Java虛擬機將拋出StackOverflowError。

如果可以動態擴展本機方法堆棧,並且嘗試進行本機方法堆棧擴展,但是沒有足夠的內存可用,或者沒有足夠的內存可用來爲新線程創建初始本機方法堆棧,那麼Java虛擬機將拋出OutOfMemoryError錯誤。

總結:

先簡單總結幾個,還需要再次總結.

  1. 線程共享區域:堆內存,方法區域
  2. 線程私有區域:pc寄存器,JVM堆棧,本地方法棧
  3. 方法區邏輯上屬於堆內存
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章