1. 程式人生 > >深入理解java虛擬機-java內存區域與內存溢出異常

深入理解java虛擬機-java內存區域與內存溢出異常

變量 情況 規範 服務 turn com ack 永久 ror

線程 運行數據區分為線程共享區和線程獨占區

線程獨占區的意思是每開啟一個線程就會擁有一個線程獨占區域

如下圖所示:

技術分享圖片

程序計數器:

1)是一塊較小的內存空間,可看做當前線程所執行的字節碼的行號指示器

2)它處於線程獨占區(每一個線程都會有自己的線程獨占區)

3)如果線程執行的是java方法,這個計數器記錄的就是正在執行的虛擬機字節碼指令的地址,如果正在執行的是native方法,這個計數器的值為undefined

4) 此區域是唯一一個在java虛擬機規範中沒有規定任何OutofMemory的情況的區域(開發者不操作程序計數器,由java虛擬機內部維護)

java虛擬機棧:

1)描述的是java方法執行的動態內存模型

2)棧幀:每個方法執行都會創建一個棧幀,伴隨著方法從創建到執行完成。

棧幀用於存儲局部變量表,操作數棧,動態鏈接,方法出口等。

3) 局部變量表:存放編譯器可知的各種基本數據類型,引用類型。returnAddress類型;

局部變量表的內存空間在編譯器完成分配,當進入一個方法時,這個方法需要幀分配多少內存是固定的,在方法運行期間是不會改變局部變量表的大小

4)棧大小問題: 棧滿拋StackOverFlowError 棧內存溢出

OutofMerory

本地方法棧:虛擬機棧為虛擬機執行java方法服務;本地方法棧為虛擬機執行native方法服務

java堆:

1)存放對象實例(並非所有對象實例都被存放在堆中)

2)是垃圾收集器管理的主要區域

3)新生代,老年代,Eden空間

方法區:

1)存儲虛擬機加載的類信息(包括類的版本,字段,方法,接口等描述信息),常量,靜態變量,即時編譯器編譯之後的代碼等數據

2)方法區和永久代(這兩者在HotSpot中是等價的)

3)垃圾回收在方法區的行為

4)異常定義:申請失敗會拋出OutofMemoryError

運行時常量池(屬於方法區中的一塊)

技術分享圖片

對象的創建:

方式:new關鍵字--》存儲到java堆中

技術分享圖片

遇到問題:

1)給對象分配內存:

指針碰撞法(java堆use和free很規整時使用);

技術分享圖片

空閑列表法(使用一張表來進行記錄哪些內存未使用)

2)線程安全性問題

采用線程同步方式解決;

采用本地線程分配緩沖(TLAB) 來提高一些性能

3)初始化對象

初始化之後:

抽象數據類型默認為null; 基本數據類型默認為0;boolean型默認為false

4)執行構造方法

探究對象結構:

技術分享圖片

對象的訪問定位:(如何找到對象)

1)使用句柄

2)直接指針,速度快,減少性能開銷

深入理解java虛擬機-java內存區域與內存溢出異常