1. 程式人生 > >JVM系列之一 JVM的基礎概念與記憶體區域

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

## 前言 作為一名 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