1. 程式人生 > >jvm學習筆記(1)——java虛擬機器記憶體區域

jvm學習筆記(1)——java虛擬機器記憶體區域

一、java記憶體區域:

    

1、程式計數器(執行緒私有):

    記憶體中較小的記憶體空間,可以當做當前執行緒所執行位元組碼的行號指示器。如分支、迴圈、跳轉、異常處理、執行緒恢復都需要依賴這個計數器完成。

2、java虛擬機器棧(執行緒私有):

    也就是我們通常所說的“堆疊”中的棧。棧是由一個個棧幀組成的。棧幀中存放區域性變量表、各種基本的資料型別(boolean、byte、char、short、int、float、long、double)、物件引用、方法返回地址等。當執行緒執行一個方法時,就會隨之建立一個對應的棧幀,並將建立的棧幀壓棧。當方法執行完畢之後,便會將棧幀出棧。所以遞迴呼叫容易出現StackOverflowError異常,即執行緒請求的棧深度超過了虛擬機器允許的最大深度。

    每個執行緒分配的棧的大小是設定的(-Xss來設定),棧的基本單位是棧幀。所以棧幀所佔空間越大,棧的深度就越小,反之亦然。簡單的可以理解為:棧的大小=棧幀大小平均值*棧的深度

3、本地方法棧(執行緒私有):

    與虛擬機器棧發揮的作用類似,只不過本地方法棧使用的本地方法服務(Native方法服務)。

4、java堆(所有執行緒共享):

    在虛擬機器啟動時建立,存放物件的例項。

    從GC回收的角度來說,可細分為新生代、老年代。

    更細緻的把新生代拆分為Eden空間、From Survivor空間、To Survivor空間等。

    可以通過-Xms和-Xmx控制分配的堆的大小。當堆內沒有足夠的記憶體完成例項分配,且到達堆的大小上限,會丟擲OutOfMemoryError異常,即我們經常說的OOM。

5、方法區(所有執行緒共享):

    存放已被虛擬機器載入的類的資訊、常量池、靜態變數、即時編譯器編譯後的程式碼(JIT)、64位系統上類壓縮指標等資料。

    邏輯上雖為java虛擬機器堆的一部分,為了和java堆區分開來,又稱為Non-Heap(非堆)。

    在jdk1.8之前方法區通過“永久代”(PermGen)

來實現,在jdk1.8及以後廢棄,採用“元空間”(MetaSpace)來實現。最大的區別是永久代是在jvm虛擬機器上分配的記憶體,而元空間是分配的本地記憶體。可通過-XX:MetaspaceSize-XX:MaxMetaspaceSize配置元空間分配的大小和上限。

    更細緻的拆分MetaSpace(元空間)、CodeCache(程式碼快取區,主要存放JIT編譯生成的二進位制程式碼)、CompressedClassPointSpace(壓縮類指標空間,主要用於64位系統上類壓縮指標)。

 

二、總結:

    整理下,輸出個思維導圖。

 

參考資料:

《深入理解JAVA虛擬機器》