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)
更細緻的拆分MetaSpace(元空間)、CodeCache(程式碼快取區,主要存放JIT編譯生成的二進位制程式碼)、CompressedClassPointSpace(壓縮類指標空間,主要用於64位系統上類壓縮指標)。
二、總結:
整理下,輸出個思維導圖。
參考資料:
《深入理解JAVA虛擬機器》