Java虚拟机运行模型_Java虚拟机的执行模型

java代码是在线程中被执行的。每个线程都有它自己的执行栈,这个栈由很多帧组成。每个帧代表了一个方法调用:每当一个方法被调用时,就会创建一个新的帧,然后将这个帧放到当前线程的执行栈的栈顶。当这个方法正常返回时,或者发生了异常,这个帧就会从执行栈顶弹出,然后虚拟机会接着执行下一个位于执行栈栈顶的帧。

每个帧都包含两部分:一个局部变量区和一个操作数栈区。局部变量区包含了方法中定义的局部变量,可以通过索引值来随即访问。操作数栈区,如它的名字暗示,它是一个包含操作数的栈,这些数据被字节码指令所使用。这意味着这个栈中的数据只能以后进先出的顺序访问。

局部变量区和操作数栈的大小是由方法中的代码决定的。它们的大小是在编译时计算的,然后随着字节码指令一起存储在编译后的类中。

fbcfe083b3d3cede94c7d0e5ac5cdd8b.png

当帧被创建的时候,操作数栈初始化为空,局部变量包含当前对象的引用this(非静态方法)以及方法的参数。

局部变量区和操作数栈区的每一个插槽(图3.1中的方框)都能存储java中的任何值,除了long型和double型的值。因为long和double值需要2个插槽。

字节码指令可以划分为两类:1将局部变量的值传递到操作数栈的一小部分指令集,另外一部分指令2在操作数栈上进行操作:它们取得栈顶上的一些数据,进行计算,获得结果,然后将结果放回栈顶。

常见的指令1:

ILOAD,LLOAD,FLOAD,DLOAD和ALOAD指令读取一个局部变量的值,然后将它放置到操作数栈,这些指令的参数就是需要读取的局部变量的索引值i。

ISTORE,LSTORE,FSTORE,DSTORE和ASTORE指令是用来从操作数栈取得相应的数据然后保存会局部变量,它们的参数也是索引值i。

示例:

packagepkg;public classBean {private intf;public intgetF() {return this.f;

}public void setF(intf) {this.f =f;

}

}

其中getter方法的字节码为:

ALOAD 0

GETFIELD pkg/Bean f I

IRETURN

第一条指令读取索引位置为0的局部变量this,这个局部变量是在这个方法调用时创建的帧的过程中被初始化的,然后将这个局部变量放置到操作数栈栈顶。第二条指令从栈顶弹出这个值,this,然后将字段f的值放置到栈顶,this.f。最后一条指令从栈顶弹出得到的字段f的值,将它返回给调用者。这个方法执行过程中帧的状态如图

412c74c4bb56a9cf60c877541b5dd6cb.png

Setter方法的字节码如下:

ALOAD 0

ILOAD 1

PUTFIELD pkg/Bean f I

RETURN

第一条指令将this放置到操作数栈栈顶。第二条指令将索引为1的局部变量值放置到栈顶,这个索引的值为方法的参数,在方法调用创建帧的过程中初始化的。第三个指令从栈顶弹出这两个值,并将int值存贮到this对象的字段f中,this.f。最后一条指令,在源代码中是隐

式定义的,但是在编译后的代码中是必须的,它负责销毁执行帧并将调用返回给调用者。这个方法的执行帧的状态如图:

43e8cea364e9dccf92a2698f86b71e49.png

再看一个实际工作代码中某个类的一个方法

java代码如下:

/*** 并行计算各Handler

*@paramservices

*@paramdescriberMap

*@paramitems

*@paramsnapshots

*@paramareaId

*@paramoption

*@paramcontext

*@paramfees

*@paramdemoteLines*/

private void asynHandle(List services, Map describerMap, List items, Mapsnapshots,long areaId, DeliveryQueryOption option, MojoContext context, List fees, ListdemoteLines) {

Mailbox exitmb = new Mailbox();

FlowTask resTask= newFlowTask();for(Long service : services) {if(DeliveryConstant.ignoreServices.contains(service)) {continue;

}

PostageDescriberDO describer=describerMap.get(service);if (describer != null && describer.getType().intValue() !=DeliveryConstant.DELIVERY_TYPE_ADV) {

MojoEvent event= newMojoEvent(items, snapshots, service, areaId, option, context);

FlowTask preTask= newHandlerCalTask(event, fees, demoteLines);

Long dependencyType=DeliveryConstant.serviceMapping.get(service);

Mailbox exitFlag = new Mailbox();if(dependencyType != null &&services.contains(dependencyType)) {

MojoEvent mojoEvent= newMojoEvent(items, snapshots, dependencyType, areaId, option, context);

FlowTask task= newHandlerCalTask(mojoEvent, fees, demoteLines);

Mailbox exitMsg = new Mailbox();

preTask.informOnExit(exitMsg);//开启执行前置任务

preTask.start();//添加子任务

resTask.addSubFlowTask(task);

task.informOnExit(exitFlag);//preTask设置为task的前置任务,通过exitMsg识别

task.addPreTaskExtMsg(exitMsg);

}else{//添加子任务

resTask.addSubFlowTask(preTask);

preTask.informOnExit(exitFlag);

}//添加子任务完成标记

resTask.addSubTaskExtMsg(exitFlag);

}

}

resTask.start();

resTask.informOnExit(exitmb);

exitmb.getb(2000);//超时时间

}

该方法的字节码为:

private asynHandle(Ljava/util/List;Ljava/util/Map;Ljava/util/List;Ljava/util/Map;JLcom/taobao/delivery/common/transfer/query/DeliveryQueryOption;Lcom/taobao/delivery/common/mojo/MojoContext;Ljava/util/List;Ljava/util/List;)V

NEW kilim/Mailbox

DUP

INVOKESPECIAL kilim/Mailbox.()V

ASTORE11NEW com/taobao/delivery/common/kilim/FlowTask

DUP

INVOKESPECIAL com/taobao/delivery/common/kilim/FlowTask.()V

ASTORE12ALOAD1INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator;

ASTORE14GOTO L0

L1

FRAME FULL [com/taobao/delivery/common/mojo/DeliveryMojo java/util/List java/util/Map java/util/List java/util/Map J com/taobao/delivery/common/transfer/query/DeliveryQueryOption com/taobao/delivery/common/mojo/MojoContext java/util/List java/util/List kilim/Mailbox com/taobao/delivery/common/kilim/FlowTask T java/util/Iterator] []

ALOAD14INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;

CHECKCAST java/lang/Long

ASTORE13GETSTATIC com/taobao/delivery/common/constant/DeliveryConstant.ignoreServices : Ljava/util/List;

ALOAD13INVOKEINTERFACE java/util/List.contains (Ljava/lang/Object;)Z

IFEQ L2

GOTO L0

L2

FRAME FULL [com/taobao/delivery/common/mojo/DeliveryMojo java/util/List java/util/Map java/util/List java/util/Map J com/taobao/delivery/common/transfer/query/DeliveryQueryOption com/taobao/delivery/common/mojo/MojoContext java/util/List java/util/List kilim/Mailbox com/taobao/delivery/common/kilim/FlowTask java/lang/Long java/util/Iterator] []

ALOAD2ALOAD13INVOKEINTERFACE java/util/Map.get (Ljava/lang/Object;)Ljava/lang/Object;

CHECKCAST com/taobao/delivery/common/dataobject/PostageDescriberDO

ASTORE15ALOAD15IFNULL L0

ALOAD15INVOKEVIRTUAL com/taobao/delivery/common/dataobject/PostageDescriberDO.getType ()Ljava/lang/Integer;

INVOKEVIRTUAL java/lang/Integer.intValue ()I

ICONST_1

IF_ICMPEQ L0

NEW com/taobao/delivery/common/mojo/MojoEvent

DUP

ALOAD3ALOAD4ALOAD13LLOAD5INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long;

ALOAD7ALOAD8INVOKESPECIAL com/taobao/delivery/common/mojo/MojoEvent. (Ljava/util/List;Ljava/util/Map;Ljava/lang/Long;Ljava/lang/Long;Lcom/taobao/delivery/common/transfer/query/DeliveryQueryOption;Lcom/taobao/delivery/common/mojo/MojoContext;)V

ASTORE16NEW com/taobao/delivery/common/kilim/HandlerCalTask

DUP

ALOAD16ALOAD9ALOAD10INVOKESPECIAL com/taobao/delivery/common/kilim/HandlerCalTask. (Lcom/taobao/delivery/common/mojo/MojoEvent;Ljava/util/List;Ljava/util/List;)V

ASTORE17GETSTATIC com/taobao/delivery/common/constant/DeliveryConstant.serviceMapping : Ljava/util/Map;

ALOAD13INVOKEINTERFACE java/util/Map.get (Ljava/lang/Object;)Ljava/lang/Object;

CHECKCAST java/lang/Long

ASTORE18NEW kilim/Mailbox

DUP

INVOKESPECIAL kilim/Mailbox.()V

ASTORE19ALOAD18IFNULL L3

ALOAD1ALOAD18INVOKEINTERFACE java/util/List.contains (Ljava/lang/Object;)Z

IFEQ L3

NEW com/taobao/delivery/common/mojo/MojoEvent

DUP

ALOAD3ALOAD4ALOAD18LLOAD5INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long;

ALOAD7ALOAD8INVOKESPECIAL com/taobao/delivery/common/mojo/MojoEvent. (Ljava/util/List;Ljava/util/Map;Ljava/lang/Long;Ljava/lang/Long;Lcom/taobao/delivery/common/transfer/query/DeliveryQueryOption;Lcom/taobao/delivery/common/mojo/MojoContext;)V

ASTORE20NEW com/taobao/delivery/common/kilim/HandlerCalTask

DUP

ALOAD20ALOAD9ALOAD10INVOKESPECIAL com/taobao/delivery/common/kilim/HandlerCalTask. (Lcom/taobao/delivery/common/mojo/MojoEvent;Ljava/util/List;Ljava/util/List;)V

ASTORE21NEW kilim/Mailbox

DUP

INVOKESPECIAL kilim/Mailbox.()V

ASTORE22ALOAD17ALOAD22INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.informOnExit (Lkilim/Mailbox;)V

ALOAD17INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.start ()Lkilim/Task;

POP

ALOAD12ALOAD21INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.addSubFlowTask (Lcom/taobao/delivery/common/kilim/FlowTask;)V

ALOAD21ALOAD19INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.informOnExit (Lkilim/Mailbox;)V

ALOAD21ALOAD22INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.addPreTaskExtMsg (Lkilim/Mailbox;)V

GOTO L4

L3

FRAME FULL [com/taobao/delivery/common/mojo/DeliveryMojo java/util/List java/util/Map java/util/List java/util/Map J com/taobao/delivery/common/transfer/query/DeliveryQueryOption com/taobao/delivery/common/mojo/MojoContext java/util/List java/util/List kilim/Mailbox com/taobao/delivery/common/kilim/FlowTask java/lang/Long java/util/Iterator com/taobao/delivery/common/dataobject/PostageDescriberDO com/taobao/delivery/common/mojo/MojoEvent com/taobao/delivery/common/kilim/FlowTask java/lang/Long kilim/Mailbox] []

ALOAD12ALOAD17INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.addSubFlowTask (Lcom/taobao/delivery/common/kilim/FlowTask;)V

ALOAD17ALOAD19INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.informOnExit (Lkilim/Mailbox;)V

L4

FRAME SAME

ALOAD12ALOAD19INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.addSubTaskExtMsg (Lkilim/Mailbox;)V

L0

FRAME FULL [com/taobao/delivery/common/mojo/DeliveryMojo java/util/List java/util/Map java/util/List java/util/Map J com/taobao/delivery/common/transfer/query/DeliveryQueryOption com/taobao/delivery/common/mojo/MojoContext java/util/List java/util/List kilim/Mailbox com/taobao/delivery/common/kilim/FlowTask T java/util/Iterator] []

ALOAD14INVOKEINTERFACE java/util/Iterator.hasNext ()Z

IFNE L1

ALOAD12INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.start ()Lkilim/Task;

POP

ALOAD12ALOAD11INVOKEVIRTUAL com/taobao/delivery/common/kilim/FlowTask.informOnExit (Lkilim/Mailbox;)V

ALOAD11LDC2000INVOKEVIRTUAL kilim/Mailbox.getb (J)Ljava/lang/Object;

POP

RETURN

MAXSTACK= 8MAXLOCALS= 23

MAXSTACK 是方法执行时分配的局部变量区的插槽个数。

MAXLOCALS是方法执行时操作数栈的插槽个数。

ALOAD 12的意思就是加载一个非基本类型,在局部变量区插槽序号是12的一个对象类型到操作数栈顶

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值