解析:将常量池中的符号引用转换为直接引用的过程,直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。解析主要针对类或接口、字段、类方法、接口方法、方法类型等,解析的动作实际是会随着JVM在执行完初始化之后再执行的。
3.初始化阶段执行类构造器clinit()方法的过程,该方法不需要自定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来,Jvm要保证clinit()方法在多线程访问下的安全性。
机制策略 1.双亲委派模式类加载器收到了类加载的请求时,不会自己先去尝试加载这个类,而是把请求委托给父加载器去执行;
如果父加载器还存在父类加载器,则依次向上委托,因此类加载请求最终都应该被传递到顶层的启动类加载器中;
如果父类加载器可以完成类加载请求,就直接成功返回,只有当父加载器在无法完成该加载,子加载器才会尝试自己去加载该类;
2.沙箱安全机制假设自定义一个类名为String且所在包为java.lang,在使用引导类加载器加载时会先加载JDK中的String类,因为这个类本来是属于jdk的,后面再次出现String类就会报错,以此保证源代码不被恶意篡改,这就是沙箱安全机制
JVM运行时数据区
内存结构
内存是计算机的重要部件之一,它是外存与CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。JVM的内存结构规定Java程序在执行时内存的申请、划分、使用、回收的管理策略,通说来说JVM的内存管理指运行时数据区这一大块的管理。
线程运行
JVM中一个应用是可以有多个线程并行执行,线程被一对一映射为服务所在操作系统线程,调度在可用的CPU上执行,启动时会创建一个操作系统线程;当该线程终止时,这个操作系统线程也会被回收。
在虚拟机启动运行时,会创建多个线程,数据区中有的模块是线程共享的,有的是线程私有的:
线程共享:元数据区、堆Heap;
线程私有:虚拟机栈、本地方法栈、程序计数器;
单个CPU在特定时刻只能执行一个线程,所以多线程通过几块空间的使用,然后不断的争抢CPU的执行时间段。
元数据空间基本描述:方法元空间(方法区)在JVM启动的时候被创建,是被各个线程共享的内存空间,用于存放类和方法的元数据以及常量池,比如Class和Method。在实际的开发中,经常因为加载的类太多,进而导致内存溢出问题,这样可以对元空间的大小进行扩展。
与堆的关系:
元空间存放加载的类信息,当类被实例化时,堆中存储实例化的对象信息,并且通过对象类型数据的指针找到类。
堆空间基本描述:JVM启动时创建堆区,是内存管理的核心区,通常情况下也是最大的内存空间,是被所有线程共享的,几乎所有的对象实例都要在堆中分配内存,所以这里也是垃圾回收的重点空间。
堆栈关系
栈是JVM运行时的单位,堆是存储单位,当栈中方法结束,相关对象失去所有引用后,不会马上被移除堆空间,要等到垃圾收集器运行的时候。
虚拟机栈虚拟机栈(Java栈)在每个线程创建时都会生成一个虚拟机栈,栈的内部是一个个栈帧单元,对应Java方法的调用,其生命周期和线程周期保持一致。用来存储方法的局部遍历,部分执行结果,方法的调用和返回。