Java_Run-Time_Data_Areas
2019-07-02 10:41:25 0 举报
AI智能生成
Java运行时数据区
作者其他创作
大纲/内容
Java Run-Time Data Areas
程序计数器(Program Counter Register)
CPU 只有把数据装载到寄存器才能运行
存储正在执行字节码指令的地址(偏移量)和行号指示器,线程的执行和恢复等都依赖于程序计数器
Java 中的多线程,通过线程轮流切换并分配处理器执行时间的方式实现
任何一个确定的时候,一个处理器(内核),只会执行某个线程中的一条指令
此区域不会发生内存溢出(OOM)
方法区 (Method Area)
:该区用于存储以下几类数据
虚拟机已加载的类信息
静态属性
方法
JIT 编译后的机器码
运行时常量池
......
运行时常量池(Run-Time Constant Pool)
:运行时常量池用于存储编译期生成的各种字面量和符号引用,在类加载后放入方法区的运行时常量池
相关知识点
JVM 虚拟机规范定义:方法区是 JVM 运行时数据区的一个组成部分
永久代 (Perm Generation)
:永久代是 Hotspot 虚拟机中,JDK7及之前版本中的一种实现
启动时固定大小,难以调优
Full GC时,将会移动类元信息,如果动态加载类过多,容易产生 Perm 区的 OOM
JDK 7 中,将字符串常量由永久代转移到了堆中
元空间 (Metaspace)
JDK 8 中 ,使用元空间替代了永久代
元空间在本地内存中分配,空间大小受限于本地内存
类元信息、字段、静态属性、方法、常量等都移至元空间
注意:字符串常量的实际对象存储在堆空间
堆(Heap)
JVM 虚拟机规范定义:堆空间可以处于物理上不连续的内存空间,只要逻辑上是连续的即可。
程序在运行过程中,堆空间如果不断的扩容与回缩,会造成额外的系统压力
解决方案:将 JVM 参数 Xms 和 Xmx设置为一样大小,避免在 GC 后,调整堆大小时带来额外的压力
本地方法栈(Java Native Method Stacks)
Java 虚拟机栈(Java Virtual Machine Stacks)
:描述了 Java 方法在运行时的内存区域
栈帧(Stack Frame)
局部变量表
此区域存放三种类型的数据
基本数据类型
(slot 称为局部变量空间)
64 位长度的 long 和 double 类型变量占用 2 个 slot,其它类型变量均占用 1 个 slot
reference 类型
returnAddress 类型
此区域存放方法参数和局部变量
局部变量表所需的内存空间,会在编译期完成分配
在非静态方法中,局部变量表 索引[0] 位置上存储的是方法所属对象的实例引用,随后存储的是方法参数和局部变量
STORE 字节码指令:将操作数栈中计算完成的局部变量写回局部变量表的存储空间中
操作数栈
:操作数栈是一个初始化状态为空的桶式结构栈
JVM 的执行引擎是基于操作数栈的执行引擎
字节码指令集的定义是基于栈类型的,操作数栈的深度存储于方法元信息的 stack 属性中
i++ 和 ++i 的区别
i++
iload_1
将局部变量表中 slot_1 元素压入操作数栈
对局部变量表中的 slot_1 元素,进行 +1 操作
istore_2
将栈顶元素存储到局部变量表中的 slot_2 中
++i
对局部变量表中的 slot_1 元素,进行 + 1 操作
将局部变量表中 slot_1 元素,压入操作数栈
动态链接
每个栈帧都包含一个在常量池中对当前方法的引用,以支持方法调用过程中的动态链接
方法返回地址
方法执行过程中有两种情况可能会退出
正常退出
执行引擎执行到方法返回的字节码指令
RETURN
IRETURN
ARETURN
异常退出
无论何种退出情况,都将返回至方法当前被调用的位置
方法执行过程中退出的三种情况
返回值压出上层调用栈帧
异常信息抛给能够处理的栈帧
程序计数器指向方法调用后的下一条指令
方法退出的过程相当于弹出当前栈帧
JVM 是基于栈结构的运行环境
栈帧是方法执行的基本结构,每个方法在执行的同时,都会创建一个栈帧
方法从被调用到执行完成的过程,对应栈帧在虚拟机中入栈到出栈的过程
栈顶帧(活动栈帧):在活动线程中,只有位于栈顶的帧才是有效的,故称为栈顶帧或者活动栈帧
执行引擎运行时,所有指令都只能对活动栈帧进行操作
虚拟机通过压栈和出栈的方式,对每个方法对应的活动栈帧进行运算处理
0 条评论
回复 删除
下一页