JVM系列之一 JVM的基礎概念與記憶體區域
- 2021 年 2 月 18 日
- 筆記
- Java基礎/JVM
前言
作為一名 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