Jvm運行時數據區有哪些
程序計數器(Program Counter Register)
- 作用:
- 可以看作是當前線程所執行的字節碼的行號指示器。
- 在多線程環境下,每個線程都有自己獨立的程序計數器,線程私有的,用于記錄該線程正在執行的字節碼指令地址,以便線程切換后能恢復到正確的執行位置。
- 用來存儲指向下一條指令的地址:即將執行的指令代碼
- 特點:
- 是一塊較小的內存空間。
- 如果線程正在執行的是一個 Java 方法,程序計數器記錄的是正在執行的虛擬機字節碼指令的地址;
- 如果正在執行的是 Native 方法,這個計數器值則為空(Undefined)。
Java 虛擬機棧(Java Virtual Machine Stacks)
- 作用:
- 用于存儲方法調用的棧幀(Stack Frame)。
- 每個方法在執行時都會創建一個棧幀,用于存儲局部變量表、操作數棧、動態鏈接、方法返回地址等信息。
- 局部變量表:存放了編譯期可知的各種基本數據類型(
boolean、byte、char、short、int、float、long、double
)、對象引用(reference
類型)和returnAddress
類型(指向了一條字節碼指令的地址)
- 局部變量表:存放了編譯期可知的各種基本數據類型(
- 特點:
- 線程私有,與線程的生命周期相同,每個線程都有自己獨立的虛擬機棧。
- 棧的大小可以固定也可以動態擴展。
- 棧的深度超出了允許的范圍:拋出
StackOverflowError
異常; - 棧可以動態擴展但在擴展時無法申請到足夠的內存空間:拋出
OutOfMemoryError
異常。
- 棧的深度超出了允許的范圍:拋出
本地方法棧(Native Method Stacks)
- 作用:
- 與虛擬機棧類似,但是用于**支持本地方法(Native Method)**的執行。
- 本地方法:用其他語言(如 C、C++)實現的方法,在 Java 中可以通過
native
關鍵字聲明。
- 本地方法:用其他語言(如 C、C++)實現的方法,在 Java 中可以通過
- 與虛擬機棧類似,但是用于**支持本地方法(Native Method)**的執行。
- 特點:
- 線程私有。
- 其具體實現方式和行為可能因不同的 JVM 實現而有所差異。
- 如果本地方法棧的深度超出限制 / 在擴展時無法申請到足夠內存,也會拋出
StackOverflowError
或OutOfMemoryError
異常。
Java 堆(Java Heap)
- 作用:
- 用于存儲對象實例和數組。
- 幾乎所有的對象實例都在堆上分配內存。
- 堆是垃圾回收的主要區域(GC堆),JVM 會自動管理堆內存,回收不再使用的對象,以避免內存泄漏。
- 特點:
- 線程共享,所有線程都可以訪問堆中的對象。
- 堆的大小可以通過參數進行調整。
- 如果堆內存不足,會拋出
OutOfMemoryError
異常。
- 如果堆內存不足,會拋出
方法區(Method Area)
- 作用:
- 存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。
- 特點:
- 線程共享
- 在 Java 8 之前,方法區被稱為永久代(Permanent Generation);
- 從 Java 8 開始,使用元空間(Metaspace)來替代永久代
- 元空間使用本地內存,而不是 JVM 堆內存。
- 方法區無法滿足內存分配需求:拋出
OutOfMemoryError
異常。
運行時常量池(Runtime Constant Pool)
- 是方法區的一部分。
- 用于存放編譯期生成的各種字面量和符號引用,在類加載后進入方法區的運行時常量池中存放。
- 運行時常量池相對于Class文件常量池的一個重要特征是具備動態性,運行期間也可能將新的常量放入池中。