JVM執行時資料區域 —— 程式計數器、Java虛擬機器棧、本地方法棧、Java堆、方法區、執行時常量池
java虛擬機器執行時資料區域的概括圖如下所示:
下面將對執行時資料區進行講解
程式計數器
1、說明:程式計數器可以看做是當前執行緒所執行的位元組碼的行號指示器。其實通俗點講就是記錄class檔案執行到哪一行
2、注意的點:
(1)因為CPU執行時只能處理一個執行緒的程式碼,但是可能有多個執行緒在執行,所以需要記錄每個執行緒執行到哪裡,所以每個執行緒都有一個獨立的程式計數器。所以這類區域是 “執行緒私有” 的記憶體
(2)此區域在Java虛擬機器中是唯一一個沒有 OutOfMemory 的區域
Java虛擬機器棧
1、說明:Java虛擬機器棧描述的是 Java 方法
2、形象:一個方法執行完了就不在執行了,你可以想象一下,其實就是對應著棧這種資料結構的特點,方法呼叫時就入棧,方法執行完了就出棧
3、其實我們經常所說的 “堆疊” 中的棧指的就是這裡,更確切的說是虛擬機器棧中的區域性變量表。
4、注意:該區域會丟擲兩種異常
(1)StackOverFlowError:如果執行緒請求的棧的深度超過虛擬機器所允許的深度。因為棧你可以看做是一個井,往裡邊倒水,當水倒多了,水就溢位來了
(2)OutOfMemoryError:如果虛擬機器棧的記憶體可以動態擴充套件且擴充套件時申請不到記憶體,那麼就會報錯
5、也是 執行緒不共享 的
本地方法棧
1、說明:本地方法棧(Native Method Stack)與虛擬機器棧所發揮的作用是非常相似的,它們之間
的區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而本地方法棧則為虛
擬機使用到的Native方法服務。
2、注意:該區域與Java虛擬機器棧一樣,都會丟擲StackOverFlowError、OutOfMemoryError異常
Java堆
1、說明:java對是存放物件例項和陣列的。是所有執行緒共享的。也是垃圾回收GC的主要區域
2、Java堆可以處於物理上不連續的記憶體空間中,只要邏輯上是連續的即可,就像我們的磁碟空間一樣
方法區
1、說明:它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。方法區和堆一樣,都是執行緒共享的。
2、除了和堆一樣的記憶體資料可以不連續外,該區域可以不實現垃圾回收。該區域的記憶體回收主要是針對執行時常量池的回收和對型別的解除安裝
執行時常量池
1、說明:該區域是方法區中的一部分。主要用來存放編譯期生成的各種字面量和符號引用
2、特性:執行時常量池具備動態性。如何理解呢?就比如 String 類的 intern() 方法。如果該字串不在執行時常量池,那麼會將該字串儲存到執行時常量池中,然後將該字串的地址放回,你可以執行如下程式碼:
String aa = new String("aa");
String bb = new String("aa");
System.out.println(aa == bb);//false
String cc = new String("aa").intern();
String dd = new String("aa").intern();
System.out.println(cc == dd);//true
本文參考自:《深入理解Java虛擬機器:JVM高階特性與最佳實踐》