1. 运行时数据区概述
- JVM内存布局规定了Java运行过程中的内存申请、分配和管理策略。
- 运行时数据区分为线程私有和线程共享两种。
2. 线程私有内存
- 程序计数器:存储当前线程执行的字节码指令地址。
- 虚拟机栈:保存方法调用的局部变量和部分结果。
- 本地方法区:为线程执行本地方法提供空间。
3. 线程共享内存
- 堆:存储对象实例和数组。
- 方法区:存储类信息、常量、静态变量等。
- 堆外内存:JDK 7中的永久代或JDK 8的元空间和代码缓存。
4. 程序计数器
- 作用:指示下一条执行的字节码指令。
- 特性:线程私有,无内存溢出错误。
5. 虚拟机栈
- 栈帧:包含局部变量表、操作数栈、动态链接信息等。
- 局部变量表:存储方法参数和局部变量。
- 操作数栈:保存计算过程的中间结果。
- 动态链接:支持运行期的动态链接。
- 方法返回地址:标识方法退出后的返回位置。
6. 本地方法栈
- 管理本地方法调用,与虚拟机栈功能相似但用于非Java代码。
7. 堆内存
- 新生代:新对象创建地,包括Eden区和Survivor区。
- 老年代:长期存活对象存储地。
- 元空间:存储类元信息,替代了永久代。
8. 垃圾收集(GC)
- Minor GC:新生代的垃圾收集。
- Major GC:老年代的垃圾收集。
- Full GC:整个堆和方法区的垃圾收集。
9. TLAB(Thread Local Allocation Buffer)
- 线程私有的内存分配区域,优化内存分配性能。
10. 逃逸分析
- 优化技术,减少堆分配,可能实现栈上分配、同步省略和标量替换。
11. 方法区
- 存储类信息、常量池、静态变量等。
- 与堆分开,称为Non-Heap。
12. 方法区的演进
- JDK 1.7开始逐步去除永久代,引入元空间。
- JDK 1.8完全移除永久代,使用本地内存的元空间。
13. 运行时常量池
- 方法区的一部分,存储编译期和运行期生成的常量。
14. 方法区垃圾回收
- 回收废弃常量和不再使用的类型。
15. 性能监控与调优
- 使用工具监控内存使用情况,通过参数调整内存大小和行为。
16. 异常处理
- 异常处理信息存储在异常表中,用于异常发生时找到处理代码。
17. 动态链接与静态链接
- 动态链接将符号引用转换为直接引用。
18. 虚方法表
- 优化动态分派,使用索引表代替查找。