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程序安全稳定运行

转载于:https://www.cnblogs.com/GaryZz/p/11311801.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值