深入理解java虛擬機-java內存區域與內存溢出異常
線程 運行數據區分為線程共享區和線程獨占區
線程獨占區的意思是每開啟一個線程就會擁有一個線程獨占區域
如下圖所示:
程序計數器:
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內存區域與內存溢出異常