前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM技术总结之三——类加载机制

JVM技术总结之三——类加载机制

作者头像
剑影啸清寒
修改2020-07-20 10:23:40
4390
修改2020-07-20 10:23:40
举报
文章被收录于专栏:琦小虾的Binary琦小虾的Binary

接上篇《JVM技术总结之二——GC机制》

三. 类加载机制

参考地址: 《类加载机制-深入理解jvm》 《Java Class文件格式、常量池项目的类型、表的结构》

3.1 类的加载过程

Java 类的加载过程主要分为五步:加载验证准备解析初始化。其中验证、准备、解析可以合称为连接。此外,这五步的顺序并不是完全固定的,比如为了支持动态绑定,解析的过程可以放在初始化之后。类的加载过程如下图所示:

JVM类加载过程
JVM类加载过程

3.1.1 加载

加载过程主要做三件事情:

  1. 根据全类名获取 *.class 文件的路径,通过二进制流读入 JVM 的方法区;
  2. 在方法区中将该字节流转为方法区的运行时数据结构;
  3. 在堆中生成代表该类的 java.lang.Class 对象,Class 对象的实例作为访问方法区中运行时数据结构的访问入口

3.1.2 校验

校验阶段主要确保 Class 文件字节流中的内容不会违反当前 JVM 的规范,不会危害到 JVM 运行时的安全。主要验证的有文件格式、元数据、字节码、符号引用

3.1.3 准备

准备阶段主要是将为类变量分配内存,并初始化为默认值。以下面的片段为例:

public static int value = 111;

需要注意的是,在准备阶段对于 int 类型,初始默认值为 0 而不是 111。同样的,其他基本类型的初始默认值都是该基本类型的默认值(如 double 的 0.0)。将 value 赋值为 111 的操作在初始化的步骤(即 clinit 方法)中进行。

3.1.4 解析

解析是将符号引用转换为直接引用的过程。

  • 符号引用:一组用于标识类型的符号,符合 Java 虚拟机规范的常量表,例如其中一项常量池项目类型如下图所示;
  • 直接引用:在内存中能够唯一标识对象的引用。可以是内存指针、偏移量、或者是能间接定位到目标的句柄等。
常量池项目类型
常量池项目类型

3.1.5 初始化

执行类构建方法 clinit 的过程。clinit 方法由所有类变量的赋值动作静态语句块 static{} 合并而来,这其中也包含了父类的 clinit 方法(类变量赋值动作与父类的静态语句块),同时在执行一个类的 clinit 方法时,也会通过递归方式保证其父类的 clinit 方法先被调用

此外对于初始化阶段,只有几种情况才会要求类立刻执行 clinit 方法:

  1. new:new 关键字某个未被初始化的类;
  2. 父类:初始化某子类时,父类未被初始化,则先初始化父类;
  3. 反射:通过反射调用某个未初始化的类;
  4. main 方法所在类

3.2 类加载器

ClassLoader 中有一个 ClassLoader parent,记录其父类加载器。根类加载器 bootstrap ClassLoader 是最顶层的 ClassLoader,没有父类加载器。类加载器的加载范围不同,如果子类加载器想要加载父类加载器已经加载的类,可以通过双亲委派机制,直接访问父类加载器已经加载的类。 但是有的时候父类加载器也需要加载子类加载器的 Class,这时候就需要打破双亲委派机制,主要方式是使用 Thread 类里的线程上下文类加载器的方法 setContextClassLoader。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-07-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三. 类加载机制
  • 3.1 类的加载过程
    • 3.1.1 加载
      • 3.1.2 校验
        • 3.1.3 准备
          • 3.1.4 解析
            • 3.1.5 初始化
            • 3.2 类加载器
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档