深入理解java虛擬機-第一章:java虛擬機內存結構


1.結構分佈


2.每個區域解析




--------------割---------------

以下爲CSDN上編輯的,版本很難看,上面的Excel整理版。


   模塊名稱                                          線程                            作用存儲對象               備註    
程序計數器私有當前線程所執行字節碼的行號指示器,
通過改變這個計數器的值來選取下一條將要執行的字節碼指令。
數字每個線程都會有一個,線程之間互不影響,獨立存儲。
共享垃圾收集器管理的主要區域;
可以處於物理上不連續而邏輯上連續的內存空間中。

對象實例內存中最大一塊;
可擴展;

-Xms參數設置初始值

-Xmx參數設置最大值

內存不夠分配實例存儲空間時拋出OutOfMemoryError異常
虛擬機棧私有

描述的是java方法執行的內存模型:每個方法在執行的同時多會創建一個棧幀用於存儲局部變量表、操作數棧、動態鏈表、方法出口等信息。

每一個方法從調用直至完成的過程,就對應着一個棧幀在虛擬機中入棧到出棧的過程。

局部變量表:存放了編譯期可指的基本類型(8大類型)、對象引用(引用指針,句柄)、returnAddress類型。


生命週期與線程相同;
如果線程請求的棧深度大於虛擬機允許的深度,會報StackOverFlowError;
如果虛擬機棧擴展無法獲取做夠的內存空間時,會報OutOfMemoryError。
本地方法棧

爲虛擬機用到的native方法服務。


方法區共享別名:永久代
用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據;



運行時常量池                     
是方法區的一部分;編譯期生成的字面量和符號引用 

3.對象訪問

java最簡單的對象訪問,也會涉及到java棧、java堆、方法區三個重要的部分。

以Object object = new Object();爲例:

Object object   這部分語義將反映到java棧中的本地變量表中,即reference引用。

new Object() 這部分語義反映在java堆中,形成了存儲Object類型所有數據值的結構化內存。注:在java堆中還必須存儲有能找到此對象類型數據(對象類型、父類、實現接口、方法),這些類型數據存儲在方法區中。

引用訪問java堆中對象具體位置的方式有兩種:句柄和直接指針。
a)句柄
使用句柄方式訪問對象,則會在java堆中劃分出一塊內存作爲句柄池,引用中存儲的是對象的句柄地址;
句柄中存儲了對象實例地址和類型數據的地址。
優點:引用中直接存儲的是穩定的句柄地址,在對象被移動的情況下不需要改變引用,而是改變句柄中的實例數據指針。



b)直接指針
使用直接指針的方式,在java棧中的引用將直接存儲對象地址;但是在java堆的佈局中就必須考慮如何設置訪問類型數據的相關信息。
優點:訪問速度快,相比較於句柄訪問對象的方式而言,節省了一次指針定位的時間開銷。

4.java堆溢出和棧溢出


a.堆溢出拋出 java.lang.OutOfMemoryError。
可能原因:
1)內存泄露。垃圾回收器不能自動回收。
2)實際所需內存值過大,或者對象生命週期過長或者持有時間過長。
解決辦法:
java堆參數設置:-xms 堆最小值;-xmx 堆最大值 。

b.棧溢出

解決辦法:
棧對應的設置參數爲:-Xss 棧容量。
c.運行時常量池溢出
因爲運行時常量池分配在方法區內,我們可以通過 -XX:PermSize 和 -xx:ManPermSize來限制方法區的大小來解決。
d.本地直接內存溢出
通過 -XX:MaxDirectMemorySize 來設定。





















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