1.說明
此係列文章爲學習《深入理解JAVA虛擬機》筆記,平時也有了解JAVA虛擬機,但始終感覺學習得不夠系統深入,正好趁現在工作不算太忙,所以打算靜下心來好好研讀一些此書。
2.Java內存區域及說明
區域 | 用途 | 說明 |
---|---|---|
程序計數器 | 線程執行時的行號指示器 | 1.記錄下一次要執行的字節碼指令地址 2.唯一一個不存在內存溢出區域 3.線程私有 4.執行Native方法時,計數器值爲空(undefined) |
虛擬機棧 | 存放對象引用,局部變量表,方法出口等信息 | 1.線程私有 2.存入 StackOverflowError 和OutOfmemoryError 異常 |
本地方法棧 | 虛擬機執行native方法用到的區域 | 1.線程私有 2.存入 StackOverflowError 和OutOfmemoryError 異常 |
堆 | 主要用於創建實例對象區域,垃圾回收主要區域 | 1.線程共有 2.會拋出 OutOfmemoryError |
方法區 | 存放類信息、常量、靜態變量、即時編譯後的代碼 | 1.包含運行時常量池 2.線程共有 3.會拋出 OutOfmemoryError |
直接內存 | 直接操作native函數庫的內存,其引用存放在jav堆中的DirectByteBuffer 對象中 |
1.會拋出OutOfmemoryError |
3.對象的內存佈局
在HotSpot虛擬機中,對象在內存中存儲的佈局可以分爲3塊區域:對象頭(Header)、實例數據(Instance Data)和對象填充(Padding),這三部份保存的信息如下所示
區域 | 信息 |
---|---|
對象頭 | 1.用於保存對象自身的運行時數據,如哈希碼(HashCode)、GC分代年齡、鎖狀態標誌等 2.官方稱爲 Mark Word 3.在32位空間中的25bit保存哈希碼、4bit保存分代年齡、2bit用於保存標誌位、1bit固定爲0 4.保存類型指針,即保存該對象是屬於那一個實例所有的指針,如果保存數組時,還會保存數組長度 |
實例數據 | 保存對象的屬性中儲存的內容,保存順序受虛擬機分配策略和對象中定義屬性順序有關,通常將屬性相同的類型保存在一起 |
對齊填充 | 非必須,僅佔位符作用 |
4.對象訪問方式
- 句柄
在堆內存中維護一個句柄池,虛擬機棧中保存句柄池地址,句柄池中保存
對象實例數據指針
和對象類型數據指針
,
優點:存儲的是句柄地址,對象移動時改變實例數據指針,棧中reference
維護地址不用修改
缺點:查找對象需要二次定位,增加了指針定位的時間開銷
- 直接指針
棧中引用
reference
直接保存對象地址,而堆中必須自己維護對象類型數據指針引用
優點:速度快,不需要指針二次定位,減少指針定位的時間開銷
缺點:需要堆中維護對象類型指針