1.内存区域
1.1 程序计数器
- 线程公有,内存小
- 字节码解释器工作是就是通过扭转这个计数器的值来选取下一条须要执行指令的字节码指令,分支、循环、跳转、异样解决、线程复原等根底性能都须要依赖计数器实现。多线程切换的时候通过程序计数器明确该线程执行到了哪里
- 如果线程执行的是java办法,程序计数器记录的是字节码指令的地址。如果执行的是Native办法,程序计数器为空(Undefined)
1.2 Java虚拟机栈
- 线程公有
- 虚拟机栈外部是由一个个栈帧组成,每个办法从开始执行到执行完结对应着一个栈帧从虚拟机栈中入栈出栈的过程
- 一个栈帧又包含局部变量表、操作数栈、动静链接、办法返回地址等信息
- 办法有限递归调用会抛出StackOverflowError
局部变量表:存储着编译器可知的各种根本数据类型、对象援用类型地址、returnAddress类型(指向了一条字节码指令的地址),局部变量表的大小在编译器就能够确定了,所以在运行期内存大小不会变动
操作数栈:java虚拟机栈中的一个用于计算的长期数据存储区
1.3 本地办法栈
线程公有。区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 办法(也就是字节码)服务,而本地办法栈则为虚拟机应用到的 Native 办法服务,HotSpot JVM把本地办法栈和虚拟机栈合二为一
1.4 堆
线程共享。堆是内存区域中最大的一块,也是JVM垃圾回收的次要区域,又被称作GC堆。次要寄存的是对象实例和数组
依照GC分代垃圾回收算法,堆又分为新生代(Eden区、From Survivor区和To Survivor区)和老年代。
1.5 办法区
- 线程共享。次要寄存已被虚拟机加载的类信息、常量、动态变量、即时编译器编译后的代码等数据
- 运行时常量池:办法区的一部分,用于寄存编译期生成的各种字面量和符号援用,运行期间能够通过String类的intern()办法动静放入池中
- 办法区作为JVM 的标准,jdk1.8之前办法区的jvm实现是永恒代(PermGen space),1.8之后jvm的实现是元空间(metaspace),区别是元空间不在虚拟机中,而应用的是本地内存
- 办法区演变过程,见下图
2. 对象的拜访定位
2.1 句柄拜访
Java 堆中会调配一块内存作为句柄池。reference 存储的是句柄地址。详情见图
2.2 间接指针拜访
reference 中间接存储对象实例数据和类信息地址
2.3 优缺点
应用句柄最大的益处是reference中存储的是稳固的句柄地址,在对象挪动(GC)时只须要扭转其中的指针地址,reference不须要扭转。间接指针拜访的最大益处是速度快,节俭了一次指针拜访定位的工夫开销。所以如果对象频繁拜访的话间接指针成果好,如果对象频繁GC的话句柄拜访成果好