Java虚拟机jvm学习四:类加载器
Java虚拟机jvm学习四:类加载器
silence88 发表于10个月前
Java虚拟机jvm学习四:类加载器
  • 发表于 10个月前
  • 阅读 16
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

一、class装载验证流程

1、加载

取得类的二进制流

转为方法区数据结构

在Java堆中生成对应的java.lang.Class对象

2、链接

  • 验证:保证Class流的格式是正确的。
    • 文件格式的验证

      是否以0xCAFEBABE开头

      版本号是否合理

    • 元数据验证(语义语法是否正确)

      是否有父类

      继承了final类?

      非抽象类实现了所有的抽象方法

    • 字节码验证 (很复杂)

      运行检查

      栈数据类型和操作码数据参数吻合

      跳转指令指定到合理的位置

    • 符号引用验证

      常量池中描述类是否存在

      访问的方法或字段是否存在且有足够的权限

  • 准备
    • –分配内存,并为类设置初始值 (因为初始化的是类信息,所以在方法区中)

      public static int v=1;在准备阶段中,v会被设置为0,在初始化的<clinit>中才被设置1。

      对于static final类型,在准备阶段就会被赋上正确的值:public static final  int v=1;

  • 解析
    • 符号引用替换为直接引用:

      • 什么是符号引用?符号引用是一个字符串,它给出了被引用的内容的名字并且可能会包含一些其他关于这个被引用项的信息——这些信息必须足以唯一的识别一个类、字段、方法。这样,对于其他类的符号引用必须给出类的全名。对于其他类的字段,必须给出类名、字段名以及字段描述符。对于其他类的方法的引用必须给出类名、方法名以及方法的描述符。

      • 什么是直接引用?也就是我们说的地址

3、初始化

真正执行你编写的代码,依上而下执行代码,主要包括static变量赋值语句以及static代码块,然后执行构造函数<clinit>,子类的<clinit>调用前保证父类的<clinit>被调用,<clinit>是线程安全的。

类什么时候才被初始化?

1)创建类的实例,也就是new一个对象

2)访问某个类或接口的静态变量,或者对该静态变量赋值

3)调用类的静态方法

4)反射(Class.forName("com.lyj.load"))

5)初始化一个类的子类(会首先初始化子类的父类)

6)JVM启动时标明的启动类,即文件名和类名相同的那个类

只有这6中情况才会导致类的类的初始化。

二、Classloader

1、什么是类装载器ClassLoader

  • ClassLoader是一个抽象类
  • ClassLoader的实例将读入Java字节码将类装载到JVM中
  • ClassLoader可以定制,满足不同的字节码流获取方式
  • ClassLoader负责类装载过程中的加载阶段
标签: JVM Monitor
共有 人打赏支持
粉丝 7
博文 56
码字总数 71242
×
silence88
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: