扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: Java > JVM高频面试题 > 21.简述类加载过程

类加载过程也就是类的生命周期的前五部分,加载验证准备解析初始化

加载

在加载部分,虚拟机需要完成以下三件事:

  • 通过一个类的全限定名来获取定义此类的二进制字节流
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

验证

验证的目的是为了确保Classw文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全。验证主要分为四个阶段:文件格式验证元数据验证字节码验证符号引用验证

  • 文件格式验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本虚拟机处理,例如主、次版本号是否在当前虚拟机处理范围之内
  • 元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求,例如这个类是否有父类,这个类的父类是否继承了不允许被继承的类等
  • 字节码验证:通过数据流的控制流分析,确定程序语义是合法的、符合逻辑的。在对元数据信息中的数据类型做完校验后,字节码验证是对类的方法体进行校验分析,保证被校验类的方法在运行时不会做出危害虚拟机安全的事件,例如保证跳转指令不会跳转到方法体以外的字节码指令上
  • 符号引用验证:符号引用验证可以看做是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验,例如符号引用中通过字符串描述的全限定名是否可以找到对应的类

准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区分配。注意:这时候进行内存分配的只有类变量,不包括实例变量,其次,这里指的初始值一般是数据类型的零值,public static int x = 1;,变量x在准备阶段被设置的初始值是0而不是1,而程序被编译之后,x的值才为1。

解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,符号引用是指以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时可以无歧义定位到目标即可。直接引用是指直接指向目标的指针、相对偏移量或是一个可以直接定位到目标的句柄。

看了上面符号引用和直接引用的概念,相信很多人还是一头雾水,那符号引用转为直接引用有什么用呢?

其实符号引用就是通过一组符号来描述所引用的目标,符号引用与虚拟机实现的内存布局无关,引用的目标并不一定加载内存中,这时虚拟机并不知道对象的内存地址,所以光有符号引用是不够的。而直接引用是可以指向目标的指针,是和虚拟机实现的内存布局相关的,也就是可以确定对象在内存中的位置的。

简单来说就是在编译的时候,类会编译成一个class文件,但在编译的时候虚拟机并不直到知道所引用类的地址,这时就用符号引用来替代了,在解析时将符号引用转为直接引用就是因为直接引用可以找到类在内存中的地址。

初始化

初始化是类加载的最后一步,也是类加载的最后一步,从这开始JVM开始真正执行类中定义的Java代码


点击面试手册,获取本站面试手册PDF完整版