类加载

我们知道在运行Java程序时,首先需要把源代码编译成二进制文件也就是class文件,然后虚拟机才能执行。那虚拟机在执行class文件时,都进行了哪些步骤呢。下面我们将详细分享一下。当类也就是class文件被加载到虚拟机内存开始,到卸载出内存为止。它将要执行以下7个步骤:

  • 加载
  • 验证
  • 准备
  • 解析
  • 初始化
  • 使用
  • 卸载

下面我们看一下每一个阶段的详细流程。

  • 加载

加载也就是把class文件加载到虚拟机内存中。在加载时虚拟机需要完成3个方面的工作:

  1. 通过一个类的全限定名来获取类的二进制字节流。
  2. 将字节流所代表的静态存储结构转化为方法区中的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象。

在加载完成后,虚拟机将这个二进制流存储在虚拟机的方法区中,并且通过在内存中生成的java.lang.Class对象可以访问方法区中的类型数据。

  • 验证

验证的目的是保证加载的class文件中的字节流是符合虚拟机要求的,并且不会威胁虚拟机的安全。在验证阶段虚拟机主要分为4个步骤来验证:

  1. 文件格式验证:主要的验证是验证二进制流是否符合Class文件的规范,并且是否能被当前版本的虚拟机处理。只有通过这个阶段的验证,虚拟机才会把二进制流存储到虚拟机内存的方法区中。
  2. 元数据验证:这个阶段主要验证的是字节码的描述信息是否符合Java语言规范,也就是说主要对类的元信息进行语法上的检查,保证符合Java语言规范的元信息。
  3. 字节码验证:这个阶段是最复杂的也是最耗时的验证,它主要目的是对类的方法体进行验证,校验类中的方法在运行时,不会做出威胁虚拟机的安全事件。
  4. 符号引用验证:目的是将虚拟机中的符号引用转化为直接引用,保证解析动作可以正常执行。
  • 准备

准备阶段的目的是为静态变量分配内存并设置静态变量的默认初始值。并且这个阶段只会为静态变量分配内存并不包括实例变量。实例变量将在对象实例化时随着对象分配在虚拟机的堆中。设置静态变量的默认初始值并不代表是复制操作。例如:

public static int value = 1;

在虚拟机准备阶段时,上述代码中的value并不会设置为1,而是0,因为这时还没有执行Java的赋值运算。不同的基本数据类型的默认初始值是不同的,下面是它们的区别:

正常在准备阶段静态变量的初始化都是默认值,也就是上述列表中的值,但也有例外的可能,如果一个静态变量是final变量,那么在准备阶段时,此变量将会被赋值为指定的值。

public static final int value = 1;

在上述代码中,在准备阶段就会把value设置为1。

  • 解析

解析就是虚拟机将常量池中的符号引用替换成直接引用的过程。在解析时主要分为下面的几种:

  1. 类或接口的解析
  2. 字段解析
  3. 类方法解析
  4. 接口方法解析
  • 初始化

初始化阶段主要的目的是为静态变量或者静态代码块执行赋值的操作。静态代码块中的语句只能访问定义在静态代码块之前变量,定义它之后的变量,在静态代码块中可以赋值,但不却不能访问。下面我们看一下具体的代码。

public static Test {
  static {
    i = 0; // 编译没有问题 虽然静态变量的定义在静态代码码之后但依然可以赋值
    System.out.println(i); //编译出错 静态代码块只能访问在它之前定义的静态变量
  }
  static int i = 1;
}

本文分享自微信公众号 - 吉林乌拉(jilinwulacom)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 字节码执行引擎

    在上一篇我们介绍了类加载器的相关功能,在这一篇中我们在分享一下虚拟机中的另一个非常重要的功能字节码执行引擎。我们知道Java虚拟机的主要任务就是加载class文...

    吉林乌拉
  • 当Jvm遇到new关键字

    在上一篇我们知道了Jvm的内存划分,这一篇我们来具体分析一下,当我们用new关键字创建一个新对象时,Jvm都做了哪些工作。当虚拟机执行到new指令时,发现它是关...

    吉林乌拉
  • 自动创建代理-DefaultAdvisorAutoProxyCreator

    在上一篇中我们通过BeanNameAutoProxyCreator类中的beanNames属性来自动的匹配需要增强的对象,那么在这一篇中我们将使用一种更智能的类...

    吉林乌拉
  • 2020-09-08:KVM和OpenStack的区别?

    [此答案来自知乎](https://www.zhihu.com/question/419987391)

    福大大架构师每日一题
  • Linux NAT网络设置访问外网

    1.查看本地实体机的VMNet8的属性, ? 物理机VMNet8信息.png 实体机的网络信息 本地实体机的IP4地址:192.168.92.2 子网掩码...

    sparkle123
  • 理解Vmware虚拟机的网络模式

    命名方式VMnet0,VMnet1,VMnet......以此类推,默认情况下在vm里面已经有一些映射如下:

    我是攻城师
  • 理解Vmware虚拟机的网络模式

    像物理交换机一样,虚拟交换机将虚拟网络连接在一起,故而也被称为虚拟网络 命名方式VMnet0,VMnet1,VMnet......以此类推,默认情况下在vm里面...

    我是攻城师
  • 你必须知道的云计算知识(上)

    最近订阅学习了《深入浅出云计算》专栏,一口气学完之后,做了一些总结笔记形成此文,特分享与你,希望对你有所帮助!本文为上半部分,主要总结了IaaS篇的核心要点。

    Edison Zhou
  • 沙箱程序之虚拟机篇

    最顶层是管理虚拟机的入口,linux开源套件 libvirt(官网:www.libvirt.org):

    战神伽罗
  • 公有云服务选择八大评测标准

    说到选择一家公有云提供商,成本往往是首要因素。但是虚拟机迁移、存储和自动扩展等其他因素也应该加以考虑。 随着许多企业组织迁移到公有云或混合云,它们免不了要选择一...

    静一

扫码关注云+社区

领取腾讯云代金券