JVM系列之一 JVM的基礎概念與記憶體區域

東北小狐狸發表於2021-02-18

前言

作為一名 Java 語言的使用者,學習 JVM 有助於解決程式執行過程中出現的問題、寫出效能更高的程式碼。

可以說:學好 JVM 是成為中高階 Java 工程師的必經之路。

有感於從未整理歸納 JVM 相關的知識,所以打算寫一系列 JVM 相關的文章,以加深鞏固習得成果,為後續遺忘提供快速找回之途徑。

一、JVM 是什麼?

Java 虛擬機器 (簡稱JVM,Java Virtual Machine) ,是執行 Java 程式的平臺,準確來說,是執行位元組碼的平臺。

Java 為達成 Write Once, Run Everywhere 的目標,對於不同作業系統有不同的虛擬機器實現,使用class 位元組碼作為中間碼,JVM 執行位元組碼完成程式功能。

二、JVM的記憶體區域

1、程式計數器

程式計數器(Program Counter Register)是一小塊執行緒私有的記憶體區域,生命週期與執行緒相同,可看作是當前執行緒執行位元組碼的行號指示器。是 JVM 中唯一一個不會出現 OOM(OutOfMemeryError)的區域。

如果執行緒執行的是一個 Java 方法,計數器記錄的是正在執行的虛擬機器位元組碼指令的地址;
如果執行的是一個 Native 方法,則計數器值為空。

2、虛擬機器棧

虛擬機器棧(Virtual Machine Stack)是執行緒私有的記憶體區域,生命週期與執行緒相同描述著Java方法執行的記憶體模型:每個方法在執行時都會建立一個棧幀(Stack Frame)用於儲存區域性變數表、運算元棧、動態連結、方法出口等資訊。每個方法執行完成就對應著銷燬這個棧幀,即出棧。

此區域只會出現兩種異常:

  • StackOverflowError:當申請的棧深度達到 JVM 允許的最大深度時丟擲。
  • OutOfMemeryError:如果虛擬機器棧可動態擴充套件,但申請不到足夠記憶體時丟擲。

3、本地方法棧

本地方法棧(Native Method Stack)與虛擬機器棧作用類似,也是執行緒私有的記憶體區域,區別在於執行的是本地方法(Native Method)。

本地方法,即非Java語言實現的方法,比如C,使用本地方法可以擴充Java沒有的語言特性。

4、堆

堆(Heap)是執行緒共享的記憶體區域,是JVM管理中最大的記憶體區域,唯一作用就是存放物件例項是 JVM 垃圾收集的主要區域

5、方法區

方法區(Method Area)又名非堆(Non-Heap)是執行緒共享的記憶體區域,儲存著被 JVM 載入的類資訊、常量、靜態變數、即時編譯器編譯後的二進位制等資料

6、執行時常量池

執行時常量池(Runtime Constant Pool)是方法區的一部分,用於存放編譯期生成的字面量和符號引用,這部分內容將在類載入後進入方法區執行時常量池中存放。

7、直接記憶體

直接記憶體(Direct Memery)即通過native方法直接分配在堆外的記憶體。它不是JVM虛擬機器執行時資料區的一部分,也不在JVM規範中定義,但這部分記憶體使用頻繁,也可能導致OOM。

總結

JVM 是一個執行著位元組碼的平臺,其執行時資料區包含 程式計數器、虛擬機器方法棧、本地方法棧、堆、方法區,前三者是執行緒私有(隔離)的,後兩者是執行緒共享的。

以上就是JVM的基本概念與其執行時資料區記憶體的內容。

參考

  • 《深入理解Java虛擬機器 第2版》周志明著

本文同步釋出於本人csdn

相關文章