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的記憶體區域
![](https://img2020.cnblogs.com/blog/1149398/202102/1149398-20210218093150092-40676586.png)
### 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](https://blog.csdn.net/u012586326/article/details/112