"In-depth understanding of java virtual machine" study notes five - Chapter VI

Chapter VI class file structure

1, the cornerstone of independence

  • Various virtual machines and all platforms use different platforms are unified program storage format - the building blocks of byte code is platform-independent.
  • Basis to achieve language independence is still a virtual machine storage and bytecode format, Java virtual machine and does not in any language including Java bindings can only be associated with this particular class file binary file format.
  • class file contains a Java virtual machine instruction set and the symbol table as well as a number of other supporting information.

2, class file structure

Overview:

  • class file is a set of octet-based binary stream, the respective data items are arranged in the exact order in the compact class file.
  • class file format uses a pseudo-C language data structure to store data similar to the configuration of this dummy data structure contains two data tables and unsigned types.
  • Unsigned belong to the basic data types, from u1, u2, u4, u8 to represent one byte, two bytes, four bytes, eight bytes unsigned. Unsigned number can be used to describe a number, index, value or reference number 7 configured according utf-8 string value encoding.
  • A plurality of tables are unsigned or other complex data types as a table configuration of the data item. All the tables are habitually end with "_info". Description data represents the composite structure of the hierarchical relationship of the whole class file is essentially a table.

Magic number:

  • Each class file header magic number is four, the role is to determine whether the file is a virtual machine that can be referenced to accept class files, magic numerical class file is 0xCAFEBABE.

class version of the file:

  • Followed by four bytes stored magic number is the version number of the class file, the fifth and sixth bytes are the minor version number, 7 and 8 is the major version number.

Constant pool:

  • Followed by the major version number is constant pool entry, constant pool can be understood as a warehouse class resource file, it is the largest type of class file data structure associated with other projects, but also occupies one of the largest class file space data items while it is the type of data table class file first appears.
  • Due to the constant value of the constant pool is not fixed, so constant pool entry to be placed in a type of data represents u2 capacity constant pool count value, counting from the beginning.
  • The constant pool storing two main constants, literal and symbolic references, literal constant relatively close to the concept of Java language level, such as text strings, declared as final the constant pools.
  • And reference symbol name descriptor includes a fully qualified name of the class and interface, the name and descriptor fields and methods.
  • Each is a constant in the constant pool table, determined according to the type of project flag.
    Copy the code
    package com.ecut.clazz;
    
    public class TestClass {
        private int m; public int inc() { return m + 1; } }
    Copy the code

    Byte code file corresponding hexadecimal follows:

    Constant capacitance value of 22 represents the count of 21 constant, a constant flag of 0x0A is, according to the following table, the corresponding item type CONSTANT_Methodref_info, symbol representative of this type of class of the method of reference, the item corresponding to the type of structure there are two index, the first index is a decimal i.e. 4 to 0x0004, 0x0012 for the second index that is 18 decimal. The second constant is so, this type of project CONSTANT_Fieldref_info, i.e. the first index is decimal 3 0x0003, 0x0013 for the second index that is 19 decimal.
  • The remaining constants can use tools javap class file byte code to bytecode file output TestClass.class content. Using javap -verbose TestClass.class command.

Access flags:

  • After the end of the constant pool, followed by two bytes represent access flag. This flag is used to identify some of the class or interface level access information, including a class or interface type whether it is public, whether it is abstract. The specific meaning of the flag and the flags in the following table:
  • access_flag in a total of 16-bit flags may be used, wherein only defines the current 8, do not use the flag 0 is always required.
  • And using the modified public TestClass compiler after jdk1.2 been compiled, so it should be the value of the flag access_flag 100001 = 0x21.

Class index, the parent index, interface index:

  • Class index expression for determining the fully qualified name of this class, a parent class index for determining the fully qualified name of the parent class of this class, the index set is used to describe the interface to the class implements those interfaces that implements statement by the left an interface arranged to the right miniature set.

Fields set of tables:

  • Used to describe variables declared within a class or an interface. Field includes a class instance variables and class variables level, but does not include local variables declared within the method.
  • Field collection does not list inherited from the field from the superclass or parent class interface, but it may not originally listed fields, such as adding instance fields outside of class in order to maintain the outer class will be accessible within the class .
  • Field contains information: Scope (public, private, protected) field, class variables or instance variables (static modifier), the variability (Final), concurrency (volatile modifier, whether to force read from main memory), Can be serialized (transient modifier), field data type (basic type, object, array), the field name.
  • Field modifiers placed access_flag project, which includes two name_index and descript_index, they are references to the constant pool, representing the simple field names and field descriptors.
  • Field table structure as shown below:
  • Before binding constants in the constant pool understood class index com / ecut / clazz / TestClass, parent index java / lang / Object. Int type comprising TestClass m is a private modified.                                                 

Methods Table Collection:

  • The method includes accessing a set of flag table, the index name, a descriptor index, a set of attributes. If the parent class method is not overridden in a subclass method, no method for an information from the parent class method table set.
  • The method table structure as shown below:

Table set of attributes:

  • 在class文件中,字段表方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。
  • 属性集合的结构如下图:
  • 结合常量池对文件进行分析可得,方法容量为2包含了两个方法,第一个方法时public修饰void init,该方法包含了一个属性code,code操作数栈最大值为1.第二个方法时public修饰的int inc()该方法也包含了一个属性code。

  • Exception属性列举出方法中可能抛出的异常,也就是方法描述时在throws关键字后面列出的异常。
  • LineNumberTable属性用于描述Java源码行号和字节码行号之间的对应关系。
  • LocalVariableTable属性用来描述栈帧中局部变量与Java源码中定义的变量之间的关系。
  • SourceFile属性用来记录生成这个class源码文件名称。

3、字节码指令

概述:

  • Java虚拟机的指令由一个字节长度的,代表着某中特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(称为操作数)而构成。
  • Java虚拟机采用面向操作数栈的架构所以大多数指令都不包含操作数只有一个操作码。
  • 在Java虚拟机的指令集中大多数指令都包含了其操作锁对应的数据类型信息。

加载和存储指令:

  • 加载存储指令用来将数据在栈帧中的局部变量和操作数栈之间来回传输。
  • 将一个局部变量加载到操作数栈iload。
  • 将一个数值从操作数栈中存储到局部变量表istore。
  • 将一个常量加载到操作数栈bipush。
  • 扩充局部变量表的访问索引的指令wide。

运算或算法指令:

  • 运算或算法指令用于对两个操作数栈上的值进行某中特定的运算,并把结果重新存入操作数栈的栈顶。

类型转换指令:

 

  • 类型转换指令可以将两种不同的数值类型进行相互转换,这种转换操作一般用于实现用户代码中的显示类型转换操作。
  • int——》long——》float——》double。

对象创建和访问指令:

  • 虽然类实例和数组都是对象但是使用不同的指令来完成创建。
  • 创建类实例的指令 new。
  • 创建数组的指令 newarray。
  • 访问类字段和实例字段 putfield 、getfield、getstatic。

操作数栈管理指令:

  • 将操作数栈的栈顶一个元素出栈pop。
  • 将栈顶两个数值交换swap。

控制转移指令:

  • 在有条件或者无条件的修改PC寄存器的值。
  • 条件分支ifea、iflt。
  • 复合条件分支lookupswich。
  • 无条件goto 。

方法调用和返回指令:

  • 方法调用指令和返回值无关,而方法返回指令是根据返回值类型来区分的。
  • invokevirtual用于调用对象的实例方法。
  • invokestatic用于调用类方法。

异常处理指令:

  • 在Java程序中显示抛出异常的操作都有athrow指令来完成。
  • Java虚拟规范还规定许多运行时异常会在其他指令检测到异常时自动抛出。

同步指令:

  • Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用管程(Monitor)来支持的。

推荐博客链接:

https://blog.csdn.net/u010349169/column/info/jvm-principle

转载请于明显处标明出处:

https://www.cnblogs.com/AmyZheng/p/10537013.html

第六章 类文件结构

1、无关性的基石

  • 各种不同平台的虚拟机与所有平台都统一使用程序存储格式——字节码是构成平台无关的基石。
  • 实现语言无关性的基础仍然是虚拟机和字节码存储格式,Java虚拟机不和包括Java在内的任何语言绑定只能与class文件这种特定的二进制文件格式所关联。
  • class文件包含了Java虚拟机指令集和符号表以及若干其他辅助信息。

2、class文件结构

概述:

  • class文件是一组以八位字节为基础的二进制流,各个数据项目严格按照顺序紧凑的排列在class文件中。
  • class文件格式采用一种类似于C语言结构的伪数据结构来存储数据,这种伪数据结构包含两种数据类型无符号和表。
  • 无符号数属于基本数据类型,从u1、u2、u4、u8来分别表示一个字节、两个字节、四个字节、八个字节的无符号数。无符号数可以用来描述数字、索引、引用7数量值或者按照utf-8编码构成字符串值。
  • 表是由多个无符号或者其他表作为数据项构成的复合数据类型。所有的表都习惯性地以“_info”结尾。表示描述有层次关系的复合结构的数据,整个class文件本质就是一张表。

魔数:

  • 每个class文件的头四位为魔数,作用是确定这个文件是否是一个能被虚拟机引用接受的class文件,class文件的魔数值是0xCAFEBABE。

class文件的版本:

  • 紧接着魔数的四个字节存储的是class文件的版本号,第5和第6个字节是次版本号,第7和第8个是主版本号。

常量池:

  • 紧接着主版本号的是常量池入口,常量池可以理解为class文件中的资源仓库,它是class文件结构中与其他项目关联的最多的数据类型,也是占有class文件空间最大的数据项目之一,同时它是class文件第一个出现的表类型数据。
  • 由于常量池的常量数值不固定,所以在常量池的入口需要放置一项u2类型的数据代表常量池容量计数值,计数是从一开始的。
  • 常量池主要存放两大常量,字面量和符号引用,字面量比较接近于Java语言层面的常量概念,如文字字符串,声明为final的常量池等。
  • 符号引用包括类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。
  • 常量池中每一项常量都是一个表,根据标志位来确定项目类型。
    Copy the code
    package com.ecut.clazz;
    
    public class TestClass {
        private int m; public int inc() { return m + 1; } }
    Copy the code

    字节码文件对应的16进制如下图:

    常量容量计数值为22则代表有21个常量,第一个常量的标志位是0x0A,根据下表可知对应的项目类型是CONSTANT_Methodref_info,此类型代表类中方法的符号引用,这个项目类型对应的结构有两个index,第一个index为0x0004为即十进制4,第二个index为0x0012即十进制18。第二个常量是以此类推,这个项目类型为CONSTANT_Fieldref_info,第一个index为0x0003即十进制3,第二个index为0x0013即十进制19。
  • 剩下的常量可以借助class文件字节码的工具javap来输出TestClass.class文件字节码内容。采用javap -verbose TestClass.class命令。

访问标志:

  • 在常量池结束之后,紧接着的两个字节代表访问标志,这个标志用于标识一些类或者接口层次的访问信息,包括是类还是接口,是否为public类型,是否为abstract。具体的标志位以及标志的含义如下表:
  • access_flag中一共有16个标志位可以使用,当前只定义了其中8个,没有使用到的标志位要求一律为0。
  • TestClass被public修饰并且使用了jdk1.2之后的编译器进行了编译,因此它的access_flag标志值应该为100001=0x21。

类索引、父类索引、接口索引:

  • 类索引用于确定表达这个类的全限定名,父类索引用于确定这个类的父类的全限定名,接口索引集合就用于描述这个类实现了那些接口,这些接口按implements语句从左到右排列在接口缩影集合中。

字段表集合:

  • 用于描述接口或类中声明的变量。字段包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。
  • 字段集合不会列出从超类中或者父类接口中继承而来的字段,但有可能列出原本没有的字段,如在内部类中为了保持外部类的访问性会加入外部类的实例字段。
  • 字段包含信息:字段的作用域(public、private、protected),是实例变量还是类变量(static修饰符),可变性(final)、并发性(volatile修饰符,是否强制从主内存读写)、可否被序列化(transient修饰符),字段数据类型(基本类型、对象、数组),字段名称。
  • 字段修饰符放在access_flag项目中,它包含两项name_index和descript_index,他们都是对常量池的引用,分别代表字段的简单名称和字段的描述符。
  • 字段表结构如下图所示:
  • 结合之前的常量池中的常量可知类索引为 com/ecut/clazz/TestClass,父类索引为 java/lang/Object。TestClass包含一个被private修饰的int 类型的m。                                                 

方法表集合:

  • 方法表集合包括访问标志、名称索引、描述符索引、属性集合。如果父类方法在子类方法中没有被重写,方法表集合中不会有来自父类的方法信息。
  • 方法表结构如下图:

属性表集合:

  • 在class文件中,字段表方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。
  • 属性集合的结构如下图:
  • 结合常量池对文件进行分析可得,方法容量为2包含了两个方法,第一个方法时public修饰void init,该方法包含了一个属性code,code操作数栈最大值为1.第二个方法时public修饰的int inc()该方法也包含了一个属性code。

  • Exception属性列举出方法中可能抛出的异常,也就是方法描述时在throws关键字后面列出的异常。
  • LineNumberTable属性用于描述Java源码行号和字节码行号之间的对应关系。
  • LocalVariableTable属性用来描述栈帧中局部变量与Java源码中定义的变量之间的关系。
  • SourceFile属性用来记录生成这个class源码文件名称。

3、字节码指令

概述:

  • Java虚拟机的指令由一个字节长度的,代表着某中特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(称为操作数)而构成。
  • Java虚拟机采用面向操作数栈的架构所以大多数指令都不包含操作数只有一个操作码。
  • 在Java虚拟机的指令集中大多数指令都包含了其操作锁对应的数据类型信息。

加载和存储指令:

  • 加载存储指令用来将数据在栈帧中的局部变量和操作数栈之间来回传输。
  • 将一个局部变量加载到操作数栈iload。
  • 将一个数值从操作数栈中存储到局部变量表istore。
  • 将一个常量加载到操作数栈bipush。
  • 扩充局部变量表的访问索引的指令wide。

运算或算法指令:

  • 运算或算法指令用于对两个操作数栈上的值进行某中特定的运算,并把结果重新存入操作数栈的栈顶。

类型转换指令:

 

  • 类型转换指令可以将两种不同的数值类型进行相互转换,这种转换操作一般用于实现用户代码中的显示类型转换操作。
  • int——》long——》float——》double。

对象创建和访问指令:

  • 虽然类实例和数组都是对象但是使用不同的指令来完成创建。
  • 创建类实例的指令 new。
  • 创建数组的指令 newarray。
  • 访问类字段和实例字段 putfield 、getfield、getstatic。

操作数栈管理指令:

  • 将操作数栈的栈顶一个元素出栈pop。
  • The top two stack values ​​exchange swap.

Control transfer instructions:

  • Conditional or unconditional value modified PC register.
  • Conditional branch ifea, iflt.
  • Compound conditional branch lookupswich.
  • Unconditional goto.

Method call and return instructions:

  • Method call instruction and a return value irrespective of the method according to the return instruction return type is distinguished.
  • Examples invokevirtual object method calls.
  • invokestatic used to call class method.

Exception handling instructions:

  • In Java programs show throwing operation has athrow instructions to complete.
  • Java Virtual specification also provides for automatic exception is thrown when an abnormality is detected in a number of other instructions run.

Synchronization instruction:

  • Java virtual machine can support an internal synchronization method and a synchronization method for a period of a sequence of instructions level, both structures are synchronized using the tube (Monitor) to the support.

Recommended blog links:

https://blog.csdn.net/u010349169/column/info/jvm-principle

Reproduced please indicate the source in a prominent place :

https://www.cnblogs.com/AmyZheng/p/10537013.html

Guess you like

Origin www.cnblogs.com/manmanchanglu/p/11621822.html