java内存结构
1.程序计数器
①作用:当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
②如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError 情况的区域。
2.Java虚拟机栈
线程私有,生命周期与线程相同,存放栈帧等信息
2.1栈帧
每一个方法被执行时都会创建一个栈帧,每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
2.1.1局部变量表
局部变量表的大小在编译期间分配,方法运行时不会改变大小。
2.1.2操作数栈
2.1.3方法返回地址
2.1.4动态链接
2.1.5附加信息
3.本地方法栈
与虚拟机栈类似,本地方法栈为虚拟机使用到的Native方法服务。
4.堆
①线程共享
②在虚拟机启动时创建,唯一目的存放对象实例
③Java堆可以处于物理不连续的内存空间中,逻辑上是连续的即可
5.方法区
①用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。
②垃圾收集行为较少。内存回收目标主要是针对常量池的回收和对类型的卸载
5.1运行时常量池
方法区的一部分
存放编译期生成的各种字面量
- 字符串
- final变量
- 类名和方法名
存放符号引用/引用量
- 类和接口的权限定名
- 字段的名称和描述符
- 方法的名称和描述符
字面量和符号引用在类加载后存放到方法区的运行时常量池中。
把翻译出来的直接引用也存储在运行时常量池中。
5.2对象类型数据
6.对象访问
主流的两种方式(见上图):使用句柄和直接指针
- 使用句柄:
使用句柄的最大好处是reference存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改
- 直接指针:
使用直接指针访问方式的最大好处就是速度更快,它节省了一次指针定位的时间开销。Sun HotSpot使用该访问方式。