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虛擬機》

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章