运行时数据区域
程序计数器
- 可以看作当前线程所执行代码的行号指示器
线程独占/私有
每个线程都有各自的程序计数器
执行java方法时记录字节码指令地址,执行native方法时为空(Undefined)
- 虚拟机中唯一一个没有OutOfMemoryError错误的区域
Java虚拟机栈
线程独占/私有
描述Java方法执行的内存模型
局部变量表
- 存放编译器可知的各种基本类型
- boolean
- byte
- char
- short
- int
- long
- float
- double
- 对象引用 : reference类型
- returnAddress类型 : 指向一条字节码指令的地址
异常信息
- StackOverflowError : 线程请求的栈深度大于虚拟机允许的栈深度
- OutOfMemeroyError :虚拟机动态扩展时,申请不到足够的内存
本地方法栈
类似与虚拟机栈,不同点是本地方法栈是为本地方法(native方法)服务的
Java堆(GC堆)
虚拟机中最大的一块内存
线程共享
用于存放对象实例
垃圾收集器工作的主要区域
内存细分
- 新生代
- Eden空间
- From Survivor
- To Survivor
- 老年代
方法区(Method Area)
线程共享
别名非堆(Non-Heap)
存储信息
- 被虚拟机加载的类信息
常量
静态变量
- 即时编译器编译后的代码
Hotspot使用永久代(PermGen)实现方法区
JDK8改用元空间(Metaspace)替代永久代
- OutOfMemeroyError : 无法满足内存分配需求时抛出
运行时常量池(Runtime Constant Pool)
- 属于方法区的一部分
- 用于存放编译期生成的各种字面量和符号引用
- 类加载后存入运行时常量池
- OutOfMemeroyError : 无法再申请到内存时抛出
直接内存(Direct Memory)
不属于虚拟机
Java NIO会用到
《深入理解Java虚拟机:JVM高级特性与最佳实践》学习笔记