Java虛擬機的運行時數據區域有程序計數器、虛擬機棧、本地方法棧、堆和方法區。
程序計數器
????????程序計數器,程序計數器是一塊較小的內存空間,可以看做是當前線程執行的字節碼的行號指示器。字節碼解釋器的工作原理就是通過修改行號計數器的值來選取將要執行的字節碼指令,分支、循環、跳轉、異常處理,線程恢復等基礎功能都需要這個計數器來完成。
????????Java虛擬機的多線程實現,是通過多個線程輪流切換并分配處理器時間的方式來實現的,在任意指定的一個時刻,一個處理器都只會執行一個線程中的指令,為了線程在切換后能夠回到指定的位置,每條線程都有一個獨立的程序計數器,,他們互不影響。
虛擬機棧
? ? ? ? 虛擬機棧和程序計數器一樣都是線程私有的。生命周期和線程是一樣的。虛擬機棧描述的是Java方法執行的內存模型。每個方法在執行的同時,都會創建一個棧幀,用來存儲局部變量表,操作數棧、動態鏈接、方法出口等信息,每一個方法從執行到結束的過程,就對應著一個棧幀在虛擬機中入棧和出棧的過程。
本地方法棧
? ? ? ? 本地方法棧和虛擬機棧的作用類似,只不過虛擬機棧是為虛擬機執行Java方法服務的,本地方法棧視為虛擬機使用到的native方法服務的。
Java堆
? ? ? ? 對于大多數應用來說,Java堆是Java虛擬機中所管理的內存中最大的一塊,Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建,這個內存的唯一目的就是存放對象實例的,幾乎上所有的對象實例都是在這里分配內存的,new產生的數據分配的內存都在這里分配。
方法區
? ? ? ? 方法區和Java堆一樣,是各個線程共享的內存區域,用于存儲yibei已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后產生的代碼等數據。
其中,線程私有的有程序計數器、虛擬機棧、本地方法棧,線程共享有Java堆,方法區。
在OutofMemoryError情況下,程序計數器是唯一一個在虛擬機規范中沒有規定任何OutOfMemoryError情況的區域。在虛擬機棧中存在兩種情況,一種是如果線程請求的棧深度大于虛擬機所允許的深度,將會拋出StackOverflowError異常,另一種情況是如果虛擬機支持動態擴展(當前大部分支持動態,但是Java虛擬機中也支持固定長度的),如果擴展時沒有申請到足夠的內存,就會拋出OutOfMemoryError異常。與虛擬機棧一樣,本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常。在Java堆中如果沒有內存完成實例分配,并且堆也無法擴展時,將會拋出OutOfMemoryError異常。在方法區中,根據Java虛擬機規范的規定,當方法區無法滿足內存分配需求時,就會拋出OutOfMemoryError異常。