JVM类加载机制

2018-09-19  本文已影响0人  旺旺大仙贝

1.类加载机制

1.1什么是类的加载

类的加载是将.class文件中的二进制数据读到内存中,并把它放到运行时数据区的方法区中,在堆区创建一个java.lang.Class对象,用来封装类在方法区中的数据结构。

1.2类的生命周期

加载

查找并加载类的二进制数据,包括

  1. 通过类的全限定名获得该类的二进制字节流数据
  2. 将这个字节流代表的静态存储结构转为方法区的运行时数据结构
  3. 在堆中生成一个代表这个类的class对象,做外外部访问方法区中数据的入口

验证

确保被加载的class类的字节流符合jvm的要求,大概完成4个阶段的验证动作

  1. 文件格式验证
  2. 元数据验证
  3. 字节码验证
  4. 符号引用验证

准备

为类的静态变量分配内存,初始化成默认值,这些在方法区中分配

  1. 仅仅对类变量(static)分配内存,不包括实例变量,实例变量在实例化时伴随对象一起分配
  2. 这里说的初始值是数据类型默认零值(0、null、false等),不是被显示赋予的值

解析

jvm将常量池内的符号引用替换为直接饮用的过程,针对类、接口、字段、类方法、接口方法、方法类型、方法句柄。

  1. 符号引用:以一组符号描述所引用对象,与jvm的内存布局无关。
  2. 直接饮用:直接指向目标的指针、相对偏移、句柄,与jvm内存布局相关。

初始化

为类的静态变量赋予正确的初始值,真正开始执行Java程序代码(字节码)。初始化步骤:

  1. 如果这个类还没有被加载和连接,先加载连接这个类;
  2. 如果这个类的父类还没有被初始化,先初始化父类;
  3. 如果类中有初始化语句,系统依次执行。

初始化时机:

  1. 创建类的实例,new

  2. 访问/赋值 类或接口的静态变量

  3. 调用类的静态方法

  4. 反射(如Class,forName("com.demo.Test"))

  5. 初始化某个类的子类,父类也会被初始化

  6. jvm启动时被标明为启动类的类(Java Test),java.exe

结束生命周期

  1. 执行System.exit()
  2. 程序正常执行结束
  3. 程序执行过程中遇到异常或错误而终止
  4. 操作系统出现错误导致jvm进程终止

1.3类加载器

有三种类加载器

1.4类的加载

类的加载有三种模式

  1. 命令行启动时由jvm初始化加载
  2. 通过Class.forName()动态加载
  3. 通过ClassLoader.loadClass()动态加载
Class.forName()和ClassLoader.loadClass()区别
Class.forName():加载.class文件同事,会对类进行解释,执行static块
ClassLoader.loadClass():只将.class文件加载到jvm中

1.5 双亲委派模型

工作流程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

上一篇 下一篇

猜你喜欢

热点阅读