## Java運行時數據區
**如下內容如未說明均以JDK1.7版本為準**

JVM內存主要分為5個部分:
* 程序計數器
* 虛擬機棧
* 本地方法棧
* 堆
* 方法區

而JDK1.8和JDK1.7比,主要是將**方法區(永久代)** 被 **元數據區**取代,而且不再在在虛擬機內存中,而是使用的本地內存。
## 程序計數器

1. 程序計數器是一塊較小內存空間,可以看做是當前線程的行號指示器,是線程私有的。
2. 字節碼解釋器工作時就是通過改變計數器的值來選取下一條需要執行的字節碼指令,來完成分支、循環、跳轉、異常處理、線程恢復等基礎功能。
3. 當前線程正在執行Java方法時,計數器記錄的是虛擬機字節碼指令地址;正在執行的是Native方法時,計數器值為空(Undefined)。
## 虛擬機棧
## 本地方法棧
## 堆

1. Java堆是虛擬機中最大的一塊區域,是線程共享的,按垃圾的分代收集算法細分為老年代和新生代,新生代又分為Eden區和幸存區,幸存區又分為From和to區。
2. 線程本地緩存區(TLAB)位于Eden區,是虛擬機保證對象的內存分配的線程安全的技術。每個線程都會有一個很小的TLAB空間,對象分配內存空間時,優先在自己的TLAB中分配,再在老年代中分配。所以堆里的TLAB區域是線程獨享的。
3. 所有對象實例及數組都要在堆上分配,除一些優化情況外(JIT編譯器優化和逃逸技術,出現棧上分配、標量替換優化)。
## 方法區

1. 虛擬機規范中定義方法區是堆的一個邏輯部分,不需要連續內存或者可擴展外,還可以不實現垃圾回收。
2. 方法區用于存放已加載的類信息、常量、靜態變量和即時編譯器編譯后的代碼。
3. 方法區內的回收主要針對常量池的回收和類的卸載。
4. 運行時常量池是方法區的一部分,存放類加載后class文件的常量信息以及String.inter()產生的新的常量。
## 直接內存
1. 直接內存并不是虛擬機運行時數據區的一部分,也不是Java虛擬機規范中定義的內存區域。
2. JDK1.4之后新加入了NIO,可以通過DirectByteBuffer類來創建和使用堆外內存,因為避免了在Java堆和Native堆中來回復制數據,從而顯著提高性能。
3. 雖然是堆外內存,但是也會受到物理內存大小的限制,所以在動態擴展時可能會出現OOM異常。
## 參考資料
* 周志明 * 《深入理解Java虛擬機》
- 面試突擊
- Java虛擬機
- 認識字節碼
- 000Java發展歷史
- 000Macos10.15.7上編譯OpenJDK8u
- 001熟悉Java內存區域
- 002熟悉HotSpot中的對象
- 003Java如何計算對象大小
- 004垃圾判定算法與4大引用
- 005回收堆和方法區中對象
- 006垃圾收集算法
- 007HotSpot虛擬機垃圾算法實現篇1
- 007HotSpot虛擬機垃圾算法實現篇2
- 007HotSpot虛擬機垃圾算法實現篇3
- 008垃圾收集器
- 009內存分配與回收策略
- 010Java虛擬機相關工具
- 011調優案例分析
- 012一次IDEA的啟動速度調優
- 013類文件Class的結構
- 014熟悉字節碼指令
- 015類加載機制(過程)
- 016類加載器
- IDEA的JVM參數
- Java基礎
- Java自動裝箱與拆箱
- Java基礎數據類型
- Java方法的參數傳遞
- Java并發
- 001走入并行的世界
- 002并行程序基礎
- 003熟悉Java內存模型JMM
- 004Java并發之volatile關鍵字
- 005線程池入門到精通
- 006Java多線程間的同步控制方法
- 007Java維基準測試框架JMH
- 008Java并發容器
- 009Java的線程實現
- 010Java關鍵字synchronized
- 011一些并行模式的熟悉
- 單例模式和不變模式
- 生產者消費者模式
- Future模式
- 012一些并行算法的熟悉
- 面試總結
- 長亮一面