JVM的类加载过程

Posted cj_eryue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM的类加载过程相关的知识,希望对你有一定的参考价值。

目录

加载

连接

验证阶段

准备阶段

解析阶段

初始化


 

 

类加载主要分为5个过程:加载验证、准备、解析初始化,其中验证、准备、解析统称为连接过程。

加载

加载分为3个阶段:

1通过类的全限定名或者类的二进制字节流JVM并没有规定字节流一定要用某种方式,可以通过压缩包(jarwar包等)、从网络上获取、动态代理生成、其他文件(JSP)、数据库、加密文件(防反编译)等。

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

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

总结这个过程就是加载二进制然后转换成JVM需要的结构,最后生成对应Class对象。

连接

验证阶段

分成4个验证过程:

1文件格式验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。在之前的文章中详细的分析class文件结构,这一步就是验证字节流的文件结构是否正确。

2元数据验证:结构正确了,这一步就是验证内容是否正确,比如里面定义的数据类型是不是都属于JVM所规定。

3字节码验证:验证字节码文件方法中的Code结构,就是验证所编写的方法是否正确合理。是整个验证过程中最复杂的一个阶段,主要目的是通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的。。

4符号引用验证:校验行为发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在解析阶段中发生,验证是否有访

问某些外部类、方法、字段的权限。

整个过程可以理解为:整体结构、结构类型、结构内容、外部引用4个步骤。

准备阶段

为类的静态变量分配内存并设置初始值。我们都知道类中的静态变量是与类一起的,并不需要初始化类的对象进行访问,所以在这个阶段把这些变量所使用的内存在方法区中进行分配,方法区是一个逻辑上的区域,在JDK 7及之前,HotSpot使用永久代来实现方法区时,实现是完全符合这种逻辑概念的;而在JDK 8及之后,类变量则会随着Class对象一起存放在Java堆中。

解析阶段

Java虚拟机将常量池内的符号引用替换为直接引用的过程

符号引用:class文件中常量池的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info这几个结构所存储的字符串常量。

直接引用:能定位到所引用的真正内容。

以上概念只是简单理解,详细理解网上较多,可以自行查看。

初始化

就是执行类构造器<clinit>()方法的过程。所谓<clinit>()方法的过程就是用户在类中定义的常量值赋值、静态代码块执行过程。在准备阶段已经对常量值设置初始值,在这里就是对常量设置用户定义的值,比如在类中存在如下一行代码:

public static final int i = 5;

准备阶段是令i=0,而在初始化阶段则是令i=5的过程。这个过程也是静态代码块的执行过程。

通过这5个过程,类被使用的准备工作就完成了,接下来才可以直接对类进行使用,比如使用类的静态常量、new一个类的实例等操作。

本文参考:一张图总览类加载的过程

以上是关于JVM的类加载过程的主要内容,如果未能解决你的问题,请参考以下文章

JVM的类加载过程

JVM的类加载过程

深入理解JVM(③)虚拟机的类加载过程

JVM中的类加载机制

JVM笔记:Java虚拟机的类加载机制

Java的虚拟机(JVM)的类加载子系统的解析过程 - Break易站