区块链技术博客
www.b2bchain.cn

jvm学习笔记5:虚拟机类加载机制

这篇文章主要介绍了jvm学习笔记5:虚拟机类加载机制的讲解,通过具体代码实例进行19838 讲解,并且分析了jvm学习笔记5:虚拟机类加载机制的详细步骤与相关技巧,需要的朋友可以参考下https://www.b2bchain.cn/?p=19838

本文实例讲述了2、树莓派设置连接WiFi,开启VNC等等的讲解。分享给大家供大家参考文章查询地址https://www.b2bchain.cn/7039.html。具体如下:

目录

  • 1. 概述
  • 2. 类的加载过程
      • 2.1 加载
      • 2.2 链接-验证
      • 2.3 链接-准备
      • 2.4 链接-解析
      • 2.5 初始化
  • 3. 类的加载时机
  • 4. 总结下各种变量的赋值阶段。

1. 概述

虚拟机把class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是类的加载机制。

2. 类的加载过程

类的生命周期如下:
jvm学习笔记5:虚拟机类加载机制
如上图:加载、验证、准备、初始化、卸载这5个阶段的顺序是确定,类的加载过程必须按照这种顺序按部就班的开始(注意:开始,而不是完成。因为可以存在两个步骤同时执行)。而解析阶段不一定:在某些情况下,可以再初始化后再开始(见动态绑定或晚期绑定)。

2.1 加载

在加载阶段,虚拟机需要完成三件事:

  1. 通过一个类的全限定名获取定义此类的二进制字节流(zip/网络/动态生成/数据库等等);
  2. 将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构;
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口(虚拟机规范没有要求class对象的存放位置,hotspot虚拟机将其放在方法区)

2.2 链接-验证

验证的目的是为了确保class文件的字节流中所包含的信息复合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

  1. 文件格式校验
    魔数、版本号、常量池等等很多
  2. 元数据校验
    对字节码的描述信息进行语义分析,以保证其描述的信息符合java语言规范。比如是否有父类、是否继承了final类等等
  3. 字节码校验
    这个阶段是整个验证过程最复杂 的一个阶段,只要目的是通过数据流和控制流分析,确保程序语义是合法的、符合逻辑的。
  4. 符号引用验证
    这个阶段发生在虚拟机将符号引用转换为直接引用的时候,这个转换动作在链接-解析阶段发生。

注:如果确认自己的代码没有问题,可以考虑使用-Xverify:none参数来关闭大部分的验证,缩短类加载时间。

2.3 链接-准备

为类变量分配内存并设置类变量初始值,这些变量所使用的内存都将在方法区中进行分配。

public static int a = 10 ;//在准备阶段分配初始值0 public static final int b = 10 ;//在准备阶段直接赋值,因为ConstantValue以及有值了 

2.4 链接-解析

解析阶段是虚拟机将常量池的符号引用替换成直接引用的过程。解析动作主要是针对常量池的类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。

一个提问,如果A类解析时,需要将B类的符号引用转换为直接引用,那么,这时候就要去加载B类。 如果B类中又有A类的符号引用需要解析,那么两者岂不是死锁了么实际是不是这样呢。 下面可以给你答案。 

虚拟机规范并没有要求解析阶段具体发生的时间,只要在使用前先进行符号解析皆可以了。

2.5 初始化

编译器自动收集类中的所所有类变量的赋值动作和静态语句块,组合成<clinit>方法。

  1. 虚拟机会保证子类的方法执行时,父类的方法已经执行完毕。
  2. 虚拟机会保证多线程环境下,只有一个线程会去执行方法。

3. 类的加载时机

java虚拟机规范并没有进行约束,可以有虚拟机自行实现。但是对于初始化阶段,虚拟机规范严格规定有且只有5种情况下必须对类进行初始化(加载、验证、准备肯定在此之前)。

  1. 遇到new、getStatic、putStatic、invokeStatic这4条字节码时。也就是对象实例化、静态变量的使用(不包括静态常量)、静态方法的调用。
  2. 使用java.lang.reflect进行反射时。
  3. 初始化一个类时,父类的方法必须已经调用。
  4. 虚拟机启动时,启动类必须初始化。
  5. 动态语言,暂时忽略。等我后面看看动态语言再说。

4. 总结下各种变量的赋值阶段。

  1. 静态常量:准备阶段赋值 public static final int a = 1;
  2. 静态变量:准备阶段赋初始值,初始化阶段赋真实值 public static int a = 1;
  3. 实例变量/常量:分配内存时先赋初始值,然后执行方法赋值。(这里好像有问题,但从字节码看,在方法中,代码是一致的,希望哪位大佬给与解答

本文转自互联网,侵权联系删除jvm学习笔记5:虚拟机类加载机制

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » jvm学习笔记5:虚拟机类加载机制
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们