深入理解java虚拟机——类加载过程

小志的博客      2022-04-27     314

关键词:

目录

一、加载阶段

1.1、加载的概述

  • “加载”是“类加载”(Class Loading)过程的一个阶段,在加载阶段,虚拟机需要完成以下3件事情:
    (1)、通过一各类的全限定名来获取定义此类的二进制字节流;
    (2)、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
    (3)、在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

1.2、加载的加载源

  • 从ZIP包中读取。
  • 从网络中获取。 最典型的应用就是Applet。
  • 运行时计算生成。 这种场景使用最多的就是动态代理技术,在java.lang.reflect.Proxy中,就是用了ProxyGenerator.generateProxyClass来为特定接口生成形式为“$Proxy”的代理类的二进制字节流。
  • 由其他文件生成。 最典型的应用就是JSP。
  • 从数据库中读取。

二、验证阶段

2.1、验证的目的

  • 为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

2.2、验证阶段完成的4个阶段检验动作

2.2.1、文件格式验证

  • 第一阶段要验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。这一阶段可能包含下面这些验证点。
    (1)、是否以魔数0xCAFEEBABE开头;
    (2)、主、次版本号是否在当前虚拟机处理范围之内;
    (3)、常量池的常量中是否有不被支持的常量类型;
    (4)、指向常量的各种索引中是否有指向不存在的常量或不符合类型的常量;
    (5)、Class文件中各个部分及文件本身是否有被删除的或附加的其他信息等等。

2.2.2、元数据验证

  • 第二阶段是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求。这个阶段可能包含下面这些验证点。
    (1)、这个类是否有父类(除了java.lang.Object之外,所有的类都应当有父类);
    (2)、这个类的父类是否继承了不允许被继承的类(被final修饰的类);
    (3)、如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法;
    (4)、类中的字段、方法、是否与父类产生矛盾(例如覆盖了父类的final字段,或者出现不符合规则的方法重载,例如方法参数都一致,但返回值类型却不同等等)。

2.2.3、字节码验证

  • 第三阶段的是整个验证过程中最复杂的一个阶段,主要目的是通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。这个阶段可能包含下面这些验证点。
    (1)、保证任意时刻操作数栈的数据类型与指令码序列都能配合工作;
    (2)、保证跳转指令不会跳转到方法体以外的字节码指令上;
    (3)、保证方法体中的类型转换是有效的等等。

2.2.4、符号引用验证

  • 最后一个阶段的校验发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在连接的第三阶段——解析阶段中发生。通常需要校验下列内容:
    (1)、符号引用中通过字符串描述的全限定名是否能找到对应的类;
    (2)、在指定类中是否存在符合方法的字段描述以及简单名称所描述的方法和字段;
    (3)、符号引用中的类、字段、方法的访问性(private、protected、public、default)是否可被当前类访问等等。

三、准备阶段

3.1、准备阶段的概述

  • 准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。

  • 这时候进行内存分配的仅包含类变量(被static修饰的变量),而不包含实例变量,实例变量将会在对象实例化时随着对象一起分配Java堆中。

  • 这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:
    public static int value = 123; 那么变量value在准备阶段过后的初始值为0而不是123。

  • 假设一个类变量的定义为: public static final int value = 123; 编译时javac将会为value生成ConstantValue属性,在准备阶段虚拟机就回根据ConstantValue的设置将fvalue赋值为123。

四、解析阶段

4.1、解析阶段的概述

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

4.2、符号引用、直接引用的概述

  • 符号引用
    符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量。
  • 直接引用
    直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。

4.3、解析动作

  • 类或接口的解析;
  • 字段解析;
  • 类方法解析;
  • 接口方法解析;

五、初始化阶段

5.1、初始化阶段的概述

  • 类初始化阶段是类加载过程的最后一步,到了初始化阶段,才真正开始执行类中定义的Java程序代码。

5.2、< clinit> 方法

  • 初始化阶段是执行类构造器< clinit> ()方法的过程。
  • < clinit> ()方法是由编译器自动收集类中所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的。
  • < clinit> ()方法与类的构函数(或者说实例构造器< init>()方法)不同,它不需要显式地调用父类构造器,虚拟机会保证在子类的 < clinit> ()方法执行之前,父类的 < clinit> ()方法已经执行完毕。
  • 由于父类的 < clinit> ()方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作。
  • < clinit> ()方法对于类或者接口来说并不是必需的,如果一个类中没有静态语句块,也没有对变量的赋值操作,name编译器可以不为这个类生成 < clinit> ()方法。
  • 接口中不能使用静态语句块,但仍然有变量初始化的赋值操作,因为接口与类一样都会生成 < clinit> ()方法。
  • 虚拟机会保证一个类的 < clinit> ()方法在多线程的环境中被正确的加锁、同步。

深入理解java虚拟机——类加载过程

目录一、加载阶段1.1、加载的概述1.2、加载的加载源二、验证阶段2.1、验证的目的2.2、验证阶段完成的4个阶段检验动作2.2.1、文件格式验证2.2.2、元数据验证2.2.3、字节码验证2.2.4、符号引用验证三、准备阶段3.1、准备阶段的概述... 查看详情

深入理解java虚拟机——类加载机制(代码片段)

文章目录类加载机制类的生命周期类的加载过程1、加载2、验证3、准备4、解析5、初始化类的初始化时机类加载器类与类加载器类加载器分类双亲委派模型工作过程源码分析双亲委派机制的好处类加载机制类的生命周期一个类型... 查看详情

深入理解java虚拟机——类加载机制概述

一、类加载机制概述虚拟机把描述类的数据从Class文件加载加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。在Java语言里面,类型的加... 查看详情

深入理解java虚拟机——类加载机制概述

一、类加载机制概述虚拟机把描述类的数据从Class文件加载加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。在Java语言里面,类型的加... 查看详情

深入理解jvm(③)虚拟机的类加载过程(代码片段)

前言上一篇我们介绍到一个类的生命周期大概分7个阶段:加载、验证、准备、解析、初始化、使用、卸载。并且也介绍了类的加载时机,下面我们将介绍一下虚拟机中类的加载的全过程。主要是类生命周期的,加载、验证、准... 查看详情

深入理解java虚拟机——类加载器

目录一、类加载器的概述二、类与加载器的概述三、类加载器的分类四、自定义类加载器并判断两个类是否相等的示例4.1自定义类加载器的步骤4.2自定义类加载器并判断两个类是否相等的代码示例五、双薪委派模型5.1、双薪委派... 查看详情

深入理解jvm读书笔记三:虚拟机类加载机制

Java虚拟机类加载机制是把Class类文件加载到内存,并对Class文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程。7.1概述与那些在编译时需要进行链接工作的语言不同,在Java语言里面,... 查看详情

深入理解java虚拟机--虚拟机类加载机制(代码片段)

...4.双亲委派机制4.1双亲委派机制说明4.2好处本文参考于《深入理解Java虚拟机》1.虚拟机类加载机制说明Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接... 查看详情

读《深入理解java虚拟机》

 Java虚拟机运行时数据区 对象的创建Java创建对象,在语言层面上使用new关键字。虚拟机遇到new关键字时,会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加... 查看详情

深入理解jvm(③)虚拟机的类加载时机(代码片段)

前言Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称为虚拟机的类加载机制。类加载的时机一个类型从被加载到虚拟机内存中... 查看详情

深入理解java虚拟机读书笔记——虚拟机类加载过程和双亲委派模型(代码片段)

学习参考资料:周志明老师的著作《深入理解Java虚拟机(第3版)》我们知道Java代码经编译后会生成Class文件,然后都需要加载到虚拟机中才能被运行和使用。而虚拟机如何加载这些Class文件,Class文件中的信... 查看详情

深入理解art虚拟机—imagespace的加载过程分析(代码片段)

上一篇《深入理解ART虚拟机—虚拟机的启动》分析了art虚拟机的启动过程,不过跳过了一个技术点,就是ImageSpace。由之前的分析可知,ClassLinker是用来加载类对象的,有三类类对象,一是ClassRoot,包括java.l... 查看详情

深入理解jvm:类加载机制

概述虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。与那些在编译时需要进行链接工作的语言不同,在Java语言里... 查看详情

《深入理解jvm——虚拟机类加载机制》

JVM深入理解JVM(5)——虚拟机类加载机制 PostedbyCrowonAugust21,2017在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。而虚拟机中,而虚拟机如何加载这些Class文件?Class文件中的信息进入到虚拟... 查看详情

《深入理解jvm——虚拟机类加载机制》(代码片段)

JVM深入理解JVM(5)——虚拟机类加载机制 PostedbyCrowonAugust21,2017在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。而虚拟机中,而虚拟机如何加载这些Class文件?Class文件中的信息进入到虚拟... 查看详情

深入理解java虚拟机第二部分.内存自动管理机制.2.hotspot虚拟机对象探秘

2、HotSpot虚拟机对象探秘 对象的创建过程1、加载类虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果... 查看详情

深入理解java虚拟机

title:深入理解Java虚拟机date:2020-05-1410:58:24tags:JVM,虚拟机目录title:深入理解Java虚拟机date:2020-05-1410:58:24tags:JVM,虚拟机1.运行时数据区域2.GC垃圾回收3.内存分配与回收策略4.类加载机制1.加载2.验证3.准备4.解析5.初始化5.类与类加载器1.... 查看详情

java虚拟机java虚拟机的类加载机制

...来总结一下java虚拟机加载一个类的过程,部分参考自《深入理解Java虚拟机》。为了避免枯燥的解说,为了让读者在读完本文后能彻底理解类加载的过程,首先来看一段java代码,我们从一个例子入手://ClassLoaderProcess.java文件class... 查看详情