JAVA 虚拟机的结构

一、结构图

JAVA 虚拟机的结构

 

1、程序计数器Program Counter Register

(1)是当前线程所执行的字节码的行号指示器

(2)由于java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。为了线程切换后能恢复到正确的执行位置,每个线程都需要一个线程私有的计数器,互不影响

(3)如果线程正在执行的是一个java方法,计数器记录的是正在执行的虚拟机字节码指令的地址如果正在执行的是一个native方法,计数器值为空

(4)是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

二、Java虚拟机栈

虚拟机栈的栈元素是栈帧,当有一个方法被调用时,代表这个方法的栈帧入栈;当这个方法返回时,代表哦这个方法的栈帧出栈。

栈帧,一部分是局部变量表,存放了编译器可知的各种基本数据类型、对象引用、returnAddress类型另一部分是操作数栈,用来存放操作数


JVM字节码指令执行1+2的过程

iconst_1 //把整数 1 压入操作数栈

iconst_2 //把整数 2 压入操作数栈

iadd //栈顶的两个数相加后出栈,结果入栈
注意,局部变量表中的变量不可直接使用,如需使用必须通过相关指令将其加载至操作数栈作为操作数使用

比如有一个方法foo(),其中的代码为:int a = 1+2;int b = a + 3;

编译为字节码就是:

iconst_1 //把整数 1 压入操作数栈

iconst_2 //把整数 2 压入操作数栈

iadd //栈顶的两个数出栈后相加,结果入栈;实际上前三步会被编译器优化为:iconst_3

istore_1 //把栈顶的内容放入局部变量表中索引为 1 的 slot 中,也就是 a 对应的空间中

iload_1 // 把局部变量表索引为 1 的 slot 中存放的变量值

加载至操作数栈iconst_3 

iadd //栈顶的两个数出栈后相加,结果入栈

istore_2 // 把栈顶的内容放入局部变量表中索引为 2 的 slot 中,也就是 b 对应的空间中

return // 方法返回指令,回到调用点

JAVA 虚拟机的结构

 

这张图是虚拟机的结构

目前只有long和double类型的数据会占用2个局部变量空间(slot)

在Java虚拟机规范中,对这个区域规定了两种异常情况:

如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常

如果虚拟机栈可以动态扩展,如果扩展时,无法申请到足够的内存,就会抛出OutOfMemoryError异常

 

三、本地方法栈

和虚拟机栈发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。

同样也会抛出StackOverflowError和OutOfMemoryError异常

 

四、方法区

线程之间共享内存会抛出OOM异常存储每个类的结构信息,如运行时常量池、字段、方法数据、构造函数、普通方法的字节码内容

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值