您当前的位置: 首页 >  jvm

玩命学JVM:认识JVM和字节码文件

发布时间:2020-10-04 18:58:34 ,浏览量:0

点击上方「蓝字」关注我们

source:https://www.cnblogs.com/cleverziv/p/13751488.html

本篇文章的思维导图

一、JVM的简单介绍 1.1 JVM是什么?

JVM (java virtual machine),java虚拟机,是一个虚构出来的计算机,但是有自己完善的硬件结构:处理器、堆栈、寄存器等。java虚拟机是用于执行字节码文件的。

1.2 JAVA为什么能跨平台?

首先我们可以问一个这样的问题,为什么 C 语言不能跨平台?如下图:

C语言在不同平台上的对应的编译器会将其编译为不同的机器码文件,不同的机器码文件只能在本平台中运行。

而java文件的执行过程如图: java通过javac将源文件编译为.class文件(字节码文件),该字节码文件遵循了JVM的规范,使其可以在不同系统的JVM下运行。

小结

  • java 代码不是直接在计算机上执行的,而是在JVM中执行的,不同操作系统下的 JVM 不同,但是会提供相同的接口。

  • javac 会先将 .java 文件编译成二进制字节码文件,字节码文件与操作系统平台无关,只面向 JVM, 注意同一段代码的字节码文件是相同的。

  • 接着JVM执行字节码文件,不同操作系统下的JVM会将同样的字节码文件映射为不同系统的API调用。

  • JVM不是跨平台的,java是跨平台的。

1.3 JVM为什么跨语言

前面提到".class文件是一种遵循了JVM规范的字节码文件",那么不难想到,只要另一种语言也同样了遵循了JVM规范,可将其源文件编译为.class文件,就也能在 JVM 上运行。如下图:

1.4 JDK、JRE、JVM的关系

我们看一下官方给的图:

1.4.1 三者定义
  • JDK:JDK(Java SE Development Kit),Java标准开发包,它提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器(javac)、Java运行时环境(JRE),以及常用的Java类库等。

  • JRE:JRE( Java Runtime Environment) 、Java运行环境,用于解释执行Java的字节码文件。普通用户而只需要安装 JRE 来运行 Java 程序。而程序开发者必须安装JDK来编译、调试程序。

  • JVM:JVM(Java Virtual Mechinal),是JRE的一部分。负责解释执行字节码文件,是可运行java字节码文件的虚拟计算机。

1.4.2 区别和联系
  1. JDK 用于开发,JRE 用于运行java程序 ;如果只是运行Java程序,可以只安装JRE,无需安装JDK。

  2. JDk包含JRE,JDK 和 JRE 中都包含 JVM。

  3. JVM 是 java 编程语言的核心并且具有平台独立性。

二、字节码文件详解

官方文档地址:https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.1

2.1 字节码文件的结构
ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}
  • "ClassFile"中的“u4、u2”等指的是每项数据的所占的长度,u4表示占4个字节,u2表示占2个字节,以此类推。

  • .class文件是以16进制组织的,一个16进制位可以用4个2进制位表示,一个2进制位是一个bit,所以一个16进制位是4个bit,两个16进制位就是8bit = 1 byte。以Main.class文件的开头cafe为例分析: 因此 u4 对应4个字节,就是 cafe babe

接下来先分析 ClassFile的结构:

  1. magic 在 class 文件开头的四个字节, 存放着 class 文件的魔数, 这个魔数是 class 文件的标志,是一个固定的值:0xcafebabe 。也就是说他是判断一个文件是不是 class 格式的文件的标准, 如果开头四个字节不是 0xcafebabe , 那么就说明它不是 class 文件, 不能被 JVM 识别。

  2. minor_version 和 major_version 次版本号和主版本号决定了该class file文件的版本,如果 major_version 记作 M,minor_version 记作 m ,则该文件的版本号为:M.m。因此,可以按字典顺序对类文件格式的版本进行排序,例如1.5 <2.0 <2.1。当且仅当v处于 Mi.0≤v≤Mj.m 的某个连续范围内时,Java 虚拟机实现才能支持版本 v 的类文件格式。范围列表如下:

  3. constant_pool_count constant_pool_count 项的值等于 constant_pool 表中的条目数加1。如果 constant_pool 索引大于零且小于 constant_pool_count,则该索引被视为有效,但 CONSTANT_Long_info 和CONSTANT_Double_info 类型的常量除外。

  4. constant_pool constant_pool 是一个结构表,表示各种字符串常量,类和接口名称,字段名称以及在ClassFile 结构及其子结构中引用的其他常量。每个 constant_pool 表条目的格式由其第一个“标签”字节指示。constant_pool 表的索引从1到 constant_pool_count-1。 Java虚拟机指令不依赖于类,接口,类实例或数组的运行时布局。相反,指令引用了constant_pool 表中的符号信息。 所有 constant_pool 表条目均具有以下常规格式:

    cp_info {
        u1 tag;
        u1 info[];
    }

constant_pool 表中的每个条目都必须以一个1字节的标签开头,该标签指示该条目表示的常量的种类。常量有17种,在下表中列出,并带有相应的标记。每个标签字节后必须跟两个或多个字节,以提供有关特定常数的信息。附加信息的格式取决于标签字节,即info数组的内容随标签的值而变化。

  1. access_flags access_flags 项的值是标志的掩码,用于表示对该类或接口的访问权限和属性。设置后,每个标志的解释在下表中指定。

  2. this_class this_class 项目的值必须是指向 constant_pool 表的有效索引。该索引处的 constant_pool 条目必须是代表此类文件定义的类或接口的 CONSTANT_Class_info 结构。

    CONSTANT_Class_info {
          u1 tag;
          u2 name_index;
    }
  3. super_class 对于一个类,父类索引的值必须为零或必须是 constant_pool 表中的有效索引。如果super_class 项的值非零,则该索引处的 constant_pool 条目必须是 CONSTANT_Class_info 结构,该结构表示此类文件定义的类的直接超类。直接超类或其任何超类都不能在其 ClassFile结构的 access_flags 项中设置 ACC_FINAL 标志。如果 super_class 项的值为零,则该类只可能是 java.lang.Object ,这是没有直接超类的唯一类或接口。对于接口,父类索引的值必须始终是 constant_pool 表中的有效索引。该索引处的 constant_pool 条目必须是 java.lang.Object 的CONSTANT_Class_info 结构。

  4. interfaces_count interfaces_count 项目的值给出了此类或接口类型的直接超接口的数量。

  5. interfaces[] 接口表的每个值都必须是 constant_pool 表中的有效索引。interfaces [i]的每个值(其中0≤i

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    111926博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0520s