1、運行時數據區域
1.1 程序計數器
程序計數器:當前線程所執行的字節碼指示器。字節碼解釋器根據這個計數器的值來選取下一條需要執行的字節碼指令。
線程私有的內存區域。唯一不會出錯OutOfMemoryError。
執行的指令分爲幾種:
1)java方法:計數器記錄的是正在執行虛擬機字節碼指令的地址;
2)Native方法:計數值爲空。
1.2 Java棧
也是線程私有的,它的生命週期跟線程相同
Java棧描述的是java方法執行的內存模型,用於存儲局部變量表、操作數棧、動態鏈接等。
兩種可能的異常:
1)如果線程請求的棧深度大於jvm棧所允許的深度,將拋出StackOverflowError;
2)如果jvm可以動態擴展,在擴展時無法申請到足夠的內存,拋出OutOfMemoryError.
通過-Xss設置大小。
1.3 本地方法棧
本地方法棧跟Java棧相似,只是它用於調用navtive方法使用,也是線程私有的,也可能拋出兩種錯誤。
1.4 Java堆
Java堆是被所有線程共享的,在jvm啓動時創建。唯一目的是存放對象實例。
Java堆是垃圾回收器管理的主要區域。
分代算法:新生代和老年代。 新生代:Eden、From Survivor、To Survivor。
Java堆可以是物理不連續的內存空間。主要通過-Xmx和-Xms控制。
如果堆空間不夠時可能會拋出OutOfMemoryError。
1.5方法區
方法區是被所有線程共享的。存儲已加載的類信息、常量、靜態變量、即時的代碼等。
在HotSpot中方法區也叫永久代(物理內存)。
該 區域的垃圾回收主要在對常量池和類型的卸載。
如果方法區無法內存分配時,會拋出OutOfMemoryError。
通過-XX:PermSize和-XX:MaxPermSize設置大小。
1.6 運行時常量池
編譯時:字面量和符號引用
運行時:String的intern()方法
1.7 直接內存
NIO引用的方法,可以直接讀取物理內存,不受jvm管控。
2、HotSpot JVM對象
2.1 對象創建
類加載-》分配堆內存-》初始化爲零值-》對象頭設置-》執行init方法
2.2 對象的內存佈局
分爲3塊:對象頭、實例數據、對齊填充
對象頭:運行時數據和類型指針。
2.3 對象的訪問定位
通過棧的reference:句柄和直接指針