java虚拟机规范阅读

https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf

 

2.5 Run-Time Data Areas

运行时数据

PC

STACK

HEAP

The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads

方法区是所有线程共享的,不过和heap的区别是,堆存储的是实例和数组

类似于,操作系统的正文段,也就是编译后的方法代码

It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.

2.5.5 Run-Time Constant Pool

运行时常量池

A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file (§4.4). It contains several kinds of constants, ranging from numeric literals known at compile-time to method and field references that must be resolved at run-time. The run-time constant pool serves a function similar to that of a symbol table for a conventional programming language, although it contains a wider range of data than a typical symbol table.

Each run-time constant pool is allocated from the Java Virtual Machine's method area (§2.5.4).

其实就是一个表,具体哪个表,参考:

IDEA使用jclasslib-bytecode-viewer插件查看字节码_newbaby2012的博客-CSDN博客

首先这些不是实例,所以不在heap,其次是所有线程共享的,所以不会再stack里

java有很多的异常处理器,exception handler

java的同步,主要通过管程来完成,通过ACC_SYNCHRONIZED标记一个方法是不是同步方法,然后有个字段代表是否有谁在访问这个同步方法,我觉得是monitorenter和moniterexit用来修改这个字段的

第三章 Java虚拟机编译器

invokespecial 指令用于调用实例初始化方法(参见§ 3.8 “使用类实例”),它也可以用
来调用父类方法和私有方法。
类方法(invokestatic)和实例方法(invokevirtual)的调用的编译代码很类似,两者的区别仅仅是实例方法需要调用者传递
this 参数而类方法则不用。所以在两种方法的局部变量表中,序号为 0 (第一个)的局部变量会
有所区别(参见§ 3.6 “接收参数”)。 invokestatic 指令用于调用类方法。
newarray方法用来创建数值数组,比如new int[10]对应newarray int
anewarray用来创建引用数组,比如new Thread[10]对应anewarray class
switch对应的指令是tableswitch和lookupswitch
异常处理

执行过程中,如果在它的编译代码第 0 4 句之间有 TestExc 异常实例被抛出,那么操作将转移至第 5 句继续执 行,即进入 catch 语句块的实现步骤。
finally
对应的jsr指令

同步
同步用的最多的地方可能是被 synchronized 修饰的同步方法。同步方法
并不是由 monitorenter monitorexit 指令来实现同步的,而是由方法调用指令读取运行时
常量池中方法的 ACC_SYNCHRONIZED 标志来隐式实现的(参见§ 2.11.10 “同步”)。
monitorenter monitorexit 指令用于实现同步语句块,比如:

ACC_SYNTHETIC  标识并非 Java 源码生成的代码。是编译器自动生成的代码
ACC_ANNOTATION   标识注解类型
<index>code[]数组中的指令的操作码的索引,此处的 code[]数组就是存储当前方法的
Java 虚拟机字节码的 Code 属性中的 code[]数组(§4.7.3 这是啥
操作码隐式包含某些操作数,譬如指令 iconst_<i> 中的 i 表示的 int
常量 −1 0 1 2 3 4 5 iconst_0 表示把 int 型的 0 值压入操作数栈

Class文件格式

A class file consists of a single ClassFile structure:

ACC_SUPER 标志用于确定该 Class 文件里面的 invokespecial 指令使用的是哪
一种执行语义。目前 Java 虚拟机的编译器都应当设置这个标志。因为invokespecial即有可能调用父类,也可能调用自己的私有方法

this_class 类索引,即常量池中的一个index,索引中的项必须是CONSTANT_Class_info 类型常量

super_class父类索引,索引中的项必须是CONSTANT_Class_info 类型常量

4.2 内部表示名称

类和接口的二进制名
Thread 的正常的二进制名是 java.lang.Thread 。在 Class 文件的内部表示形
式里面,对类 java.lang.Thrad 的引用是通过来一个代表字符串 java/lang/Thread
CONSTANT_Utf8_info 结构来实现的。
非全限定名
方法名,字段名和局部变量名都被使用非全限定名( Unqualified Names )进行存储。不能包含/ .等字符,除了<init>和<cinit>不能包含< >

字段描述

 The field descriptor of an instance variable of the multidimensional array type double[] [][] is [[[D

方法描述

签名

类签名

其中bounds定义如下:

字段类型签名

类的类型签名(不同于类的签名)

方法签名 

 4.4 常量池

 常量池由两部分组成,一个标记,一个信息,常见的标记如下

 CONSTANT_Class_info 

值得一提的是,数组也是一种对象,而他们的名字就是:

CONSTANT_Fieldref_infoCONSTANT_Methodref_info

CONSTANT_InterfaceMethodref_info 结构

class_index
项的值必须是对常量池的有效索引,常量池在该索引处的项必须是
CONSTANT_Class_info (§ 4.4.1 )结构,表示一个类或接口,当前字段或方法是这
个类或接口的成员。
CONSTANT_Methodref_info 结构的 class_index 项的类型必须是类(不能是接口)。
CONSTANT_InterfaceMethodref_info 结构的 class_index 项的类型必须是接口
(不能是类)。 CONSTANT_Fieldref_info 结构的 class_index 项的类型既可以是
类也可以是接口
name_and_type_index
name_and_type_index 项的值必须是对常量池的有效索引,常量池在该索引处的项必
须是 CONSTANT_NameAndType_info (§ 4.4.6 )结构,它表示当前字段或方法的名
字和描述符。

而CONSTANT_Utf8_info如下,哦这么看。class其实指向一个字节数组,里面其实就是类信息对应的字节码(不对,是常量String字符串),所以常量池就是CONSTANT_Utf8_info这一类CONSTANT开头的东西?

字符串常量采用改进过的 UTF-8 编码表示。这种以改进过的 UTF-8 编码中,用于表示的字符
串的码点字符序列可以包含 ASCII 中的所有非空(Non-Null)字符和所有 Unicode 编码的字符,也即字符串常量 CONSTANT_Utf8_info ,能表示所有Unicod编码的字符和ASCII码(非空)

CONSTANT_MethodHandle_info 结构

CONSTANT_MethodType_info 

CONSTANT_InvokeDynamic_info 

method_info和field_info都包含attribute_info,属性信息常见的有:

ConstantValue,Code,Exception

 

Code 属性是一个变长属性,位于 method_info (§ 4.6 )结构的属性表。一个 Code 属性
只为唯一一个方法、实例类初始化方法或类初始化方法(§ 2.9 )保存 Java 虚拟机指令及相关辅
助信息。其中Code表示如下

 

 

 field

 method 咋感觉和field一模一样

 里面的attributes_info就是

 总共有23种attributes

The number of method parameters is limited to 255 by the definition of a method descriptor (§4.3.3), where the limit includes one unit for this in the case of instance or interface method invocations.

The size of an operand stack in a frame (§2.6) is limited to 65535 values by the max_stack field of the Code attribute (§4.7.3).

Loading, Linking, and Initializing

Loading就是找到二进制文件(classloader的功能),并且据此创建class字节码文件

符号引用( symbolic reference):就是不是直接指向内存地址,类似于spring中的${ocr.port}

The Run-Time Constant Pool

运行时常量池,其实首先取决于常量池,会有很多符号引用,而这些符号引用都来自于constant_pool的各种info

All references in the run-time constant pool are initially symbolic. 

A symbolic reference to a field of a class or an interface is derived from a CONSTANT_Fieldref_info structure (§4.4.2) in the binary representation of a class or interface. Such a reference gives the name and descriptor of the field, as well as a symbolic reference to the class or interface in which the field is to be found.

一个引用会给出Field的名字和描述符,并且给出另一个引用,这个引用指向Field对应的class

Run-time constant values are derived from CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_Long_info, or CONSTANT_Double_info structures (§4.4.4, §4.4.5) in the binary representation of a class or interface.

看到5.2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值