类加载器

类加载器

  • 作用:加载Class文件。加载,初始化(Student Class)----》实例化(new)

对象都是保存在堆中的,而我们使用的对象其实是堆中对象的引用,地址

虚拟机自带的加载器

  • 启动类(根)加载器
  • 扩展类加载器
  • 应用程序(系统类)加载器

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:Loading(加载)、Verification(验证)、Preparation(准备)、Resolution(解析)、Initialization(初始化)、Using(使用)和Unloading(卸载)7个阶段。其中验证、准备、解析3个部分统称为连接(Linking)

类加载步骤:

在这里插入图片描述

这里需要注意:从类的加载→验证→准备→初始化,过程是按顺序依次开始的,但是解析比较特殊。为了支持java语言的晚期绑定/动态绑定,有时解析可以在初始化之后才开始。而且,这只是开始顺序,一个阶段通常执行的过程中会激活调用另一个阶段,所以各个阶段只是按照这个顺序开始,而不会等一个阶段完全完成后才进行下一个阶段,各个阶段是交叉混合进行的,所以各阶段并不会严格按照此顺序结束

1.Loading加载

在加载阶段,虚拟机需要完成以下3件事情:

  • 通过一个类的全限定名来获取此类的二进制字节流

    一个类的二进制字节流即.class文件,如何获取一个类的.class文件其实可以通过多种方法实现,譬如:从ZIP包中读取、从网络传输中获取、运行时计算生成(动态代理技术)、从数据库中读取等。

  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

    加载的过程中主要由【类加载器】来完成。

  • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

    某个类的java.lang.Class对象,即通常所说的一个类的类对象,这个类对象作为程序调用这个类中方法和数据调用的入口。类对象生成的方式主要有以下5种:

    1). 使用new关键字创建对象

    2). 使用Class类的newInstance方法(反射机制)

    3). 使用Constructor类的newInstance方法(反射机制)

    4). 使用Clone方法创建对象

    5). 使用(反)序列化机制创建对象。具体可以看这篇文章:
    https://blog.csdn.net/justloveyou_/article/details/72466416

2.Verification验证

验证是连接阶段的第一步,这一阶段的主要目的是为了确保Class文件的字节流包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。验证阶段是非常重要的,这个阶段是否严谨,直接决定了Java虚拟机是否能够承受恶意代码的攻击,从执行性能的角度上讲,验证阶段的工作量在虚拟机的类加载子系统中又占据了相当大的一部分。
此阶段主要包含如下几个部分的验证:
1.文件格式验证

2.元数据验证

3.字节码验证

4.符号引用验证

3.Preparation准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量使用的内存都将在方法区中进行分配。(此处需注意的是,准备阶段是为类变量分配内存并设置初始值而不是实例变量,类变量属于class,实例变量属于方法。实例变量将会在对象实例化时随着对象一起被分配在Java堆中)

4.Resolution解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析主要包括:

1.类或接口的解析

2.字段解析

3.类方法解析

4.接口方法解析

5.Initialization初始化

类初始化阶段是类加载过程的最后一步,前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的Java程序代码(字节码)。初始化对于类来说,就是执行类构造器()方法的过程

  1. 装载:

查找并加载类的二进制数据;

2)链接:

验证:确保被加载类信息符合JVM规范、没有安全方面的问题。

准备:为类的静态变量分配内存,并将其初始化为默认值。

解析:把虚拟机常量池中的符号引用转换为直接引用。

3)初始化:

为类的静态变量赋予正确的初始值。

ps:解析部分需要说明一下,Java 中,虚拟机会为每个加载的类维护一个常量池【不同于字符串常量池,这个常量池只是该类的字面值(例如类名、方法名)和符号引用的有序集合。 而字符串常量池,是整个JVM共享的】这些符号(如int a = 5;中的a)就是符号引用,而解析过程就是把它转换成指向堆中的对象地址的相对地址。

类的初始化步骤:

1)如果这个类还没有被加载和链接,那先进行加载和链接

2)假如这个类存在直接父类,并且这个类还没有被初始化(注意:在一个类加载器中,类只能初始化一次),那就初始化直接的父类(不适用于接口)

3)如果类中存在static标识的块,那就依次执行这些初始化语句。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值