Run Time Data Area 运行时数据区
Java虚拟机定义了在程序执行期间使用的各种运行时数据区域。其中一些数据区域是在Java Virtual上创建的
机器启动,只有在Java虚拟机退出时才会被销毁。其他数据区域是每个线程的。每个线程的数据区域在线程创建时创建,在线程退出时销毁。
PC Register PC寄存器
- Java虚拟机可以支持一次执行多个线程。每个Java虚拟机线程都有自己的pc(程序计数器)寄存器。
-
JVM Stacks
每一个JVM线程都有一个JVM Stack,线程创建时创建。
- JVM 栈存放栈帧(Frame)
- JVM Satck 和大多数语言(如C语言)的栈一样,存放方法计算需要的局部变量、中间结果。
- JVM规范规定,JVM Stack可以是固定大小,也可以动态扩容
- 如果线程中的计算需要的JVM Stack大小不足,JVM抛出 StackOverflowError
JVM Stack可动态扩容,但是没有内存用于扩容或创建新的线程,JVM抛出OutOfMemoryError
Heap
Heap(堆)存放多线程共享的信息(对象实例、数组等)
- 虚拟机启动时Heap创建
- Heap大小可以是固定的,也可以动态扩容收缩(可以设置堆的初始大小、动态扩容还可以设置对小、最大大小)
- Haep内存可以是不连续的
Heap内存不足时,JVM抛出OutOfMemoyError
Method Area
Method Area被多JVM线程共享
- Method存储每个类的结构,如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括在类、实例初始化和接口初始化中使用的特殊方法(
。 - Method Area在JVM启动时创建
- Method Area 逻辑上是Heap的一部分,但是jdk1.7之前不会被GC,jdk1.8之后会被FGC
- Method Area可以是固定大小,也可以动态扩容和收缩
- Method Area内存不需要连续
- jdk1.8之前,Method Area实现为Permanent Generation,jdk1.8及之后为Meta Space
Method Area内存不足,抛出OutOfMemoryError
Run_Time Constant Pool
Run_Time Constant Pool是每个类或接口的Class文件Constant_pool表运行时的表现
- Run_Time Constant Pool包含几种类型的常量,从编译时已知的数字字面值到必须在运行时解析的方法和字段引用。
- Run_Time Constant Pool使用方法区(Method Area)分配的
- Run_Time Constant Pool在JVM加载类或接口时创建
加载类或接口时,如果需要的Run_Time Constant Pool内存不足,JVM抛出OutOfMemoryError
Native Method Stacks
Native Method Stacks通常在创建每个线程时分配给每个线程
- Native Method Stacks用于存储native Method
- Native Method Stacks可以是固定大小,也可以动态扩容收缩
- 计算中,Native Method Stacks内存不足,JVM抛出StackOverflowError
Native Method Stacks动态扩容,但是内存不足,或者没有足够的内存为新线程创建初始的本机方法堆栈,那么JVM抛出OutOfMemoryError
Frames 栈帧
一个框架用于存储数据和部分结果,以及执行动态链接、返回值的方法和分派异常。
- 每个方法调用时会创建一个栈帧(frame),方法调用结束或抛出异常时该栈帧(frame)销毁
- 栈帧(Frame)是从每个线程的JVM Stacks中分配
每个frame都有自己的局部变量表(local variables),操作数堆栈(operand stack),以及当前方法类的运行时常量池的引用
Local Variables 局部变量表
每个栈帧都有自己的局部变量表,一个局部变量可以保存byte、short、int、char、float、boolean、reference、returnAnddress;一对局部变量可以存储long、double
- 局部变量通过索引来管理,从0开始。对于long、double需要占2个索引。
Operand Stacks 操作数栈
- 每个栈帧(Fame)都有一个LIFO(last-in-first-out,后进先出)的操作数栈
operand stacks 创建时为空,JVM指令可以把局部变量表、或者常量压入operand stacks,也可以操作操作数栈的内容
Dynamic Linking 动态链接
每个栈帧都有对Run_time Constant Pool的引用,以支持动态链接。
- 方法的类文件代码引用通过符号引用要调用的方法和要访问的变量。动态链接将这些符号方法引用转换为具体的方法引用,根据需要加载类来解析尚未定义的符号,并将变量访问转换为与这些变量的运行时位置相关联的存储结构中的适当偏移量。
参考文档:https://blog.csdn.net/qq_41813060/article/details/88379473
Method Invocation Completion
方法调用可正常结算,也可以是抛出异常
- 方法结束返回结果或异常
返回地址
Specail Methods
,创建对象实例只有通过JVM指令 invokespecial 调用,能在未初始化的类实例上被调用。 ,一个类或接口最多只有一个类或接口的初始化方法,并通过调用该方法进行初始化
JVM指令
Java虚拟机指令集中的类型支持
Load and Store Instructions 加载指令、存储指令
- 将局部变量加载到操作数堆栈:
- iload
- iload
_ - lload
- lload
_ - fload
- fload
_ - dload
- dload
_ - aload
- aload
_
- 将操作数堆栈中的值存储到局部变量中
- istore
- istore
_ - lstore
- lstore
_ - fstore
- fstore
_ - dstore
- dstore
_ - astore
- astore
_
- 将一个常量加载到操作数堆栈
- bipush
- sipush
- ldc
- ldc_w
- ldc2_w
- aconst_null
- iconst_m1
- iconst_
- lconst
_ - fconst
_ - dconst
_
使用更宽的索引或更大的直接操作数访问更多局部变量
Add 加法操作
- iadd
- ladd
- fadd
- dadd.
- Subtract 减法操作
- isub
- lsub
- fsub
- dsub.
- Multiply 乘法操作
- imul
- lmul
- fmul
- dmul.
- Divide 除法操作
- idiv
- ldiv
- fdiv
- ddiv.
- •Remainder 取余操作
- irem
- lrem
- frem
- drem.
- Negate 取反操作
- ineg
- lneg
- fneg
- dneg
- •Shift 移位caozuo
- ishl
- ishr
- iushr
- lshl
- lshr
- lushr
- •Bitwise OR 按位或操作
- ior
- lor
- •Bitwise AND 按位与操作
- iand
- land
- Bitwise exclusive OR 按位异或操作
- ixor
- lxor
- Local variable increment 变量自增操作
- iinc
- Comparison 比较操作
- dcmpg
- dcmpl
- fcmpg
- fcmpl
- lcmp
Type Conversion Instructions 类型转换指令
- int 转换为long、float、double
- i2l
- i2f
- i2d
- long 转为为float、double
- l2f
- l2d
- float 转换为 double
- f2d
- int 转换为byte、short、char
- i2b
- i2s
- i2c
- long 转换为 int
- l2i
- float 转换为int、long
- f2i
- f2l
double 转换为int、long、float
创建对象
- new
- 创建数组
- newarray
- anewarray
- multianewarray
- 类的访问字段(静态字段,称为类变量)和类实例的字段(非静态字段,称为实例变量)
- getstatic
- putstatic
- getfield
- putfield.
- 将局部变量表的元素加载到操作数堆栈中
- baload
- caload
- saload
- iaload
- laload
- faload
- daload
- aaload.
- 将操作数堆栈中的值存储为在局部变量表中
- bastore
- castore
- sastore
- iastore
- lastore
- fastore
- dastore
- aastore
- 获取数组长度
- arraylength
检查类实例或数组的属性
直接操作操作数堆栈
条件转移
- ifeq
- ifne
- iflt
- ifle
- ifgt
- ifge
- ifnull
- ifnonnull
- if_icmpeq
- if_icmpne
- if_icmplt
- if_icmple
- if_icmpgt
- if_icmpge
- if_acmpeq
- if_acmpne
- 复合条件分支
- tableswitch
- lookupswitch
无条件转移
invokevirtual
调用对象的实例方法,在(虚拟的)对象类型
- invokeinterface
调用接口方法,搜索由特定运行时对象实现的方法以找到适当的方法
- invokespecail
调用需要特殊处理的实例方法,无论是实例初始化方法、私有方法还是超类方法
- invokestatic
调用命名类中的类(静态)方法
- invokedynamic
调用方法,该方法是绑定到invokedynamic指令的调用站点对象的目标