JVM字节码执行模型及字节码指令集

本文深入探讨了JVM如何将Class文件的字节码转换为虚拟机栈的操作指令,详细介绍了栈帧的数据结构,包括局部变量表、操作数栈、动态链接和方法返回地址。同时,讲解了字节码指令集的构成元素,如局部变量表和操作数栈的数据传递指令,以及仅在操作数栈操作数据的指令。通过实例分析了getBean、setBean方法和构造器的字节码执行过程,为后续介绍ASM框架的CoreApi做铺垫。
摘要由CSDN通过智能技术生成

    一个Java类的生命周期概括来说需要经过加载、验证、准备、解析以及初始化、使用及卸载的过程。这里不展开加载Class 的过程以及Class文件格式(后期会陆续探讨)。在执行过程中,JVM是如何把Class文件里的字节码转换成我们的虚拟机栈的操作指令,以及整个虚拟机栈的内部数据结构是怎样的,这篇文章后续会详细介绍,并且稍微扩展下JVM规范中的一些字节码指令集。

    这篇文章的主要目的还是为了引入后续要介绍的ASM框架的CoreApi 中的Method接口和组件来做一个铺垫。我们知道,Class文件是编译后的以8byte为单位存储的二进制字节流,想要生成和解析一个Class文件,那么我们需要更好地了解在JVM中他是怎样被解析和执行的。整篇主要参考和总结了《Java Virtual Machine SpecificationJavaSE7 Version》以及《ASM 4.0 A Java bytecode engineering library》关于虚拟机执行模型及字节码执行的部分。

一、字节码执行

    方法调用在JVM中转换成的是字节码执行,字节码指令执行的数据结构就是栈帧(stack frame)。也就是在虚拟机栈中的栈元素。虚拟机会为每个方法分配一个栈帧,因为虚拟机栈是LIFO(后进先出)的,所以当前线程正在活动的栈帧,也就是栈顶的栈帧,JVM规范中称之为“CurrentFrame”,这个当前栈帧对应的方法就是“CurrentMethod”。字节码的执行操作,指的就是对当前栈帧数据结构进行的操作。

   栈帧的数据结构主要分为四个部分:局部变量表、操作数栈、动态链接以及方法返回地址(包括正常调用和异常调用的完成结果)。下面就一一介绍下这四种数据结构。

1、局部变量表(local variables)

    当方法被调用时,参数会传递到从0开始的连续的局部变量表的索引位置上。栈帧中局部变量表的长度存储在类或接口的二进制表示中。阅读Class文件会找到Code属性,所以我们能知道local variables的最大长度是在编译期间决定的。一个局部变量表的占用了32位的存储空间(一个存储单位称之为slot,槽),所以可以存储一个boolean、byte、char、short、float、int、refrence和returnAdress数据,long和double需要2个连续的局部变量表来保存,通过较小位置的索引来获取。如果被调用的是实例方法,那么第0个位置存储“this”关键字代表当前实例对象的引用。

 

2、操作数栈(operand stack)

    操作数栈同局部变量表一样,也是编译期间就能决定了其存储空间(最大的单位长度),通过 Code属性存储在类或接口的字节流中。操作数栈也是个LIFO栈。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值