类加载过程详解
类的生命周期
类从被加载到虚拟机内存中开始到卸载内存为止,它的整个生命周期简单概括加载-验证-准备-解析-初始化-使用-卸载
验证、准备、解析这三个阶段可以统称为连接。
类加载过程
Class需要加载到JVM中之后才可以被使用,那么虚拟机时如何加载这些class文件呢?
1.加载
类加载过程的第一步:主要完成三件事
- 通过全类名获取该类的二进制字节流
- 将二进制字节流里的静态存储结构转换为方法区的数据结构
- 在内存中生成一个代表该类的class对象,用于访问方法区的对象
加载这一步是由类加载器完成的,具体是哪个加载器完成是要由双亲委派选择的。
2.验证
验证这一步主要是为了检查class中二进制字节流是否符合《java虚拟机使用规范》,防止有害代码的入侵和错误信息,保障JVM的安全。会检查:文件格式、元数据、字节码、符号引用。
文件格式验证这一步是基于该类的二进制字节流进行的主要目的是检查输入的字节流是否能被正确解析并成功导入方法区中,格式上符合描述一个 Java 类型信息的要求。除了这一阶段之外,其余三个验证阶段都是基于方法区的存储结构上进行的,不会再直接读取、操作字节流了。
方法区属于是 JVM 运行时数据区域的一块逻辑区域,是各个线程共享的内存区域。当虚拟机要使用一个类时,它需要读取并解析 Class 文件获取相关信息,再将信息存入到方法区。方法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
3.准备
准备阶段是正式为类变量分配空间和赋初值的地方。
主要是对类变量(静态变量)进行分配
4.解析
解析阶段是将常量池的符号引用改为直接引用
5.初始化
初始化阶段是初始化方法<clinit()>方法的过程,是类加载的最后一步,这一步JVM才开始真正执行类中定义的java程序代码(字节码)。
6.类卸载
即类的实例对象被GC
写在满足三个条件:
- 1.所有的实例化对象都已被GC,也就是堆中不存在类的实例对象。
- 2.该类没有任何地方被引用
- 该类的类加载器的实例被GC