Java类加载机制

时间:2019-08-06
本文章向大家介绍Java类加载机制,主要包括Java类加载机制使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

什么是类的加载

将类的.class文件中的二进制数据流读入内存中,放在运行时方法区,再在中创建一个class对象,封装方法区内的数据结构。

一个类的生命周期

加载--连接--初始化--使用--卸载

其中连接又分为:验证--准备--解析

加载:

  1. 通过类的全限定名获取二进制字节流
  2. 将二进制字节流转化为方法区的运行时数据结构
  3. 在堆中生成class对象,作为访问这个方法区的入口

连接:

验证:

确保类被正确加载

确保读入二进制字节流时这些信息不会危害危害虚拟机自身安全

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

准备:

为类的静态static变量分配内存,初始化默认值

为类的静态变量赋默认值、分配内存。这个内存指的是运行时方法区的内存。

注意:这里只针对静态变量,实例变量会在对象初始化时在堆中分配。初始化默认值指的是为类初始化某一特定类型数据的初始值比如(0,null,false,etc.)

但是如果一个变量同时被static final修饰,name在准备阶段会直接赋指定的值,并不是0值

解析:

符号引用--》直接引用

符号引用:符号引用以一组符号来描述所引用的目标,符号可以是任意形式的字面量,只要使用时能无歧义的定位到目标即可。符号与虚拟机实现的内存布局无关,引用目标并不一定加载到内存中(方法区)。比如一个类引用另一个类,或者调用另一个类的变量或方法,在编译为class文件的时候,jvm并不知道其所引用的类的具体的地址,也可能这个类还没有被加载,这时候只能通过符号先进行引用

直接引用:指向目标的指针、句柄。根据虚拟机的不同可能为指针也可能为句柄。但是这个引用都是直接可以定位到被引用对象的

初始化:

为类的静态变量赋值,对类变量进行初始化。为变量指定初始值有两种可能

1.初始化变量的初始值

2.使用静态代码块为类变量指定初始值

jvm初始化步骤

  1. 如果该类还未被加载连接,则先加载连接该类
  2. 如果该类父类未被初始化,先初始化父类
  3. 如果类中有初始化语句,则依次执行初始化语句

类初始化时机

  1. new一个对象的时候
  2. 访问类的静态变量
  3. 调用类的静态方法
  4. 反射
  5. 初始化某个类的子类,父类也会被初始化
  6. 虚拟机启动的时候指定初始化某个类

类生命周期的结束

  1. 执行了System.exit()
  2. 程序运行结束
  3. 遇到异常结束
  4. jvm进程结束

双亲委派模型

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

  1. 系统类防止内存中出现多份同样的字节码
  2. 保证Java程序安全稳定运行

$flag 上一页 下一页

上一篇:wait()函数

下一篇:equals和hashCode()