## 基本概念和特性
* Java 堆內存是全局共享的
* Java 堆通常是 JVM 中最大的一塊內存區域
* Java 堆得主要作用是用于存放創建的對象實例
* JVMS 明確要求,此區域必須實現內存自動管理,即 GC;但不要求具體的 GC 實現,包括實現算法和技術
* Java 堆可以在物理上不連續空間分配,只要邏輯上連續即可
* Java 堆可能出現 OutOfMemoryError 異常
* Java 堆可以使固定大小的,也可以實現為動態擴展的,當前主流 JVM 都是可擴展的
注意:雖然 Java 堆是全局共享的,但是為了避免并發創建對象實例進行堆內存分配時的競爭關系,很有可能在 Java 堆內存在私有的線程分配緩沖區(TLAB 線程本地分配緩沖),當 TLAB 不夠用時才會加鎖向 Java 堆申請更多的內存。
由 C/C++ 延伸的 “堆內存比棧內存更快、對象分配在堆/棧內存” 等相關討論都是沒有意義的,因為 JVM 規范中,所有對象都必須在堆內分配。
## 對象分配過程
Java 堆分配對象實例的圖例大致如下:

左側代碼會讓 JVM 編譯時在 Java 虛擬機棧的局部變量表中預留一個 Solt,且類型為 reference;右側的代碼在運行時會在 Java 堆中創建對象實例,并在對象頭中存放該對象對應數據類型的指針,其指向方法區中的對象數據類型。
## JVM 內存布局選擇
一般在 JVM 實現時有兩種內存布局方案可以選擇:
第一種:如上圖所示,根據 JVM 規范要求 “一個 reference 至少能間接或者直接的查找到該對象實例的內存地址和對應數據類型”;那么局部變量表中存儲的 Solt 中的 reference 將直接指向 Java 堆中的對象實例,而該對象實例頭部指針指向方法區中的對象類型數據。
第二種:如下圖,局部變量表中的 reference 指向 Java 堆內句柄池中的某個句柄,這個句柄同時存儲對象實例的指針和對象類型數據的指針,然后兩個指針分別指向對象實例數據和對象類型數據。

兩種內存布局各有好處,第二種內存布局保證了局部變量表中 reference 指向的穩定性,因為其一直指向 Java 堆中的句柄,當 GC 時對象的頻繁移動導致對象內存地址移動時,不會影響局部變量表中的 reference 的改變;而第一種內存布局的好處在于查找對象速度會很快,對比第二種 reference 引用句柄的方式,reference 直接指向對象實例在查找對象時節省了一次指針切換開銷。Oracle HotSpot 采用的是第一種內存布局。
## 異常
如果實際所需的堆大小超過了自動內存管理所能提供的容量,那么 JVM 將拋出 OutOfMemoryError 異常;該區域是最大出現內存異常的區域。
-Xms和-Xmx 用于設置 Java 堆的最大和最小內存;如果兩個值相同,則證明 Java 堆不允許擴展。
-XX:+HeapDumpOnOutOfMemoryError 用于指定當 Java 堆出現內存溢出時,將當前內存映像信息 Dump 到磁盤鏡像中,供后續分析。
- java
- 設計模式
- 設計模式總覽
- 設計原則
- 工廠方法模式
- 抽象工廠模式
- 單例模式
- 建造者模式
- 原型模式
- 適配器模式
- 裝飾者模式
- 代理模式
- 外觀模式
- 橋接模式
- 組合模式
- 享元模式
- 策略模式
- 模板方法模式
- 觀察者模式
- 迭代子模式
- 責任鏈模式
- 命令模式
- 備忘錄模式
- 狀態模式
- 訪問者模式
- 中介者模式
- 解釋器模式
- 附錄
- JVM相關
- JVM內存結構
- Java虛擬機的內存組成以及堆內存介紹
- Java堆和棧
- 附錄-數據結構的堆棧和內存分配的堆區棧區的區別
- Java內存之Java 堆
- Java內存之虛擬機和內存區域概述
- Java 內存之方法區和運行時常量池
- Java 內存之直接內存(堆外內存)
- JAVA內存模型
- Java內存模型介紹
- 內存模型如何解決緩存一致性問題
- 深入理解Java內存模型——基礎
- 深入理解Java內存模型——重排序
- 深入理解Java內存模型——順序一致性
- 深入理解Java內存模型——volatile
- 深入理解Java內存模型——鎖
- 深入理解Java內存模型——final
- 深入理解Java內存模型——總結
- 內存可見性
- JAVA對象模型
- JVM內存結構 VS Java內存模型 VS Java對象模型
- Java的對象模型
- Java的對象頭
- HotSpot虛擬機
- HotSpot虛擬機對象探秘
- 深入分析Java的編譯原理
- Java虛擬機的鎖優化技術
- 對象和數組并不是都在堆上分配內存的
- 垃圾回收
- JVM內存管理及垃圾回收
- JVM 垃圾回收器工作原理及使用實例介紹
- JVM內存回收理論與實現(對象存活的判定)
- JVM參數及調優
- CMS GC日志分析
- JVM實用參數(一)JVM類型以及編譯器模式
- JVM實用參數(二)參數分類和即時(JIT)編譯器診斷
- JVM實用參數(三)打印所有XX參數及值
- JVM實用參數(四)內存調優
- JVM實用參數(五)新生代垃圾回收
- JVM實用參數(六) 吞吐量收集器
- JVM實用參數(七)CMS收集器
- JVM實用參數(八)GC日志
- Java性能調優原則
- JVM 優化經驗總結
- 面試題整理
- 面試題1
- java日志規約
- Spring安全
- OAtuth2.0簡介
- Spring Session 簡介(一)
- Spring Session 簡介(二)
- Spring Session 簡介(三)
- Spring Security 簡介(一)
- Spring Security 簡介(二)
- Spring Security 簡介(三)
- Spring Security 簡介(四)
- Spring Security 簡介(五)
- Spring Security Oauth2 (一)
- Spring Security Oauth2 (二)
- Spring Security Oauth2 (三)
- SpringBoot
- Shiro
- Shiro和Spring Security對比
- Shiro簡介
- Session、Cookie和Cache
- Web Socket
- Spring WebFlux