β

JVM类加载过程

Harries Blog™ 3 阅读

JVM 类加载分为5个过程:加载,验证,准备, 解析 ,初始化,使用,卸载,如下图所示:

JVM类加载过程

加载

加载是指 查找字节流 并据此 创建类 的过程。

  • (1) 数组类没有对应的字节流,它是由JVM根据元素类型和维度,创建的。
  • (2) 除了数组类,其他类都是JVM借助 BootStrap ClassLoader ClassLoader ExtClassLoader App Cla ssl oader 类加载器 来查找字节流并创建的。
  • (3) 在JVM中类的唯一性是由类的全名和类加载器确定的,相同的class文件被不同的类加载器加载生成的两个类是不同的。

连接

连接是指将创建好的类放入JVM并使之能够很好的执行的过程。

它可分为验证、准备、解析三个步骤。

  • (1) 验证阶段是为了保证创建的类能够满足JVM的约束条件,例如:jdk版本验证。
  • (2) 准备阶段的目的是 为创建的类的静态字段分配内存 ,对静态字段具体的初始化会在初始化阶段进行。
    部分虚拟机在此阶段还会构造跟其他类层次相关的 数据 结构(比如用来实现虚拟方法的动态绑定的方法表),在这个阶段该类无法知道其他类、字段及其方法的地址,因此在需要引用这些成员的时候, java 编译 器会生成一个符号引用,在运行阶段该引用才能够定位到具体的地址。
  • (3) 解析阶段的目的是将符号引用解析成实际引用,如果符号引用指向一个未被加载的成员,那个将触发JVM对这个类的加载。
    JVM规范并没有要求在连接过程中执行解析工作,它仅仅规定如果某些字段使用了符号引用,那么在执行这些 字节码 之前需要先完成对这些 富豪 饮用的解析。

初始化

初始化的目的是为标记为常量的字段赋值,以及执行 clinit 方法的过程。

在初始化一个静态字段的时候,我们可以再声明时直接赋值,也可以在静态 代码 块中对其进行赋值。

如果直接赋值的字段被 final 所修饰,并且字段为基本数据类型和String类型,那么该字段会被编译标记为常量值,其初始化直接由JVM完成。除此之外的所有直接赋值和静态代码块中赋值操作,会被java编译器放到 clinit 方法中。

什么时候需要对类进行初始化?

(1) 虚拟机启动的时候,初始化用户指定的主类。

(2) 使用new该类 实例 化对象的时候。

(3) 访问静态字段或 静态方法 时,初始化静态字段或静态方法所在类。

(4) 子类初始化会触发父类初始化。

(5) 如果接口定义了default方法,那么实现该接口的类初始化会触发该接口的初始化。

(6) 使用反射 API 的时候。

(7) 当使用JDK1.7的动态语言支持时,如果一个java.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

参考链接:

nomico271. git hub.io/2017/07/07/…

原文

https ://juejin.im/post/5bbc5f0b5188255c8a0616b0

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。 PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处: Harries Blog™ » JVM类加载过程

作者:Harries Blog™
追心中的海,逐世界的梦
原文地址:JVM类加载过程, 感谢原作者分享。

发表评论