3.4、双亲委派机制
概念:
当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。
图解:
作用:
从一定程度上可以防止危险代码的植入,保证代码安全,如果有人想替换系统级别的类:String.java。篡改它的实现,但是在这种机制下这些系统的类已经被Bootstrap classLoader加载过了,所以并不会再去加载。
防止重复加载同一个类,通过委托机制,如果级别高的加载器加载过了,就不用再加载一遍。
4、本地方法栈
5、程序计数器
每个线程都有自己私有的的一个程序计数器,一个指针,指向方法区中的方法字节码(用来存储指向下一条指令,也就是即将要执行的指令的地址),在执行引擎读取下一条指令。
程序计数器所占内存空间非常小,几乎可以忽略不计。
6、栈
栈结构解析
局部变量表
操作数栈
动态连接
在Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用一部分会在类加载阶段或第一次使用的时候转化为直接引用,这种转化称为静态解析。另外一部分将在每一次的运行期期间转化为直接引用,这部分称为动态连接。
每个栈帧都包含一个指向运行时常量池中该栈帧所属性方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。
返回地址
当一个方法开始执行后,有两种方式可以结束方法:
正常完成出口:
当程序遇到返回指令,会将返回值传递给上层的方法调用者,一般来说,调用者的PC计数器可以当成返回地址。
异常完成出口:
当程序执行遇到异常,并且没有处理或者抛出异常,就会导致方法退出,此时方法没有返回值,返回地址需要通过异常处理表来确定。
当方法返回时,可能执行的操作:
恢复上层方法的局部变量表和操作数栈
把返回值压入调用者栈帧的操作数栈
调整栈帧PC计数器的值以执行方法调用后面的一条指令
7、方法区
jdk8后在堆中的元空间中
被所有线程共享的一片区域
存放:静态的(static)、常量的(final)、类信息(构造方法、接口定义)、运行时的常量池
8、堆
一个JVM只有一个堆内存,大小可以调节
类的具体实例、类中常量、变量、方法,保存所有引用类型的真实对象
8.1、堆结构