虚拟机---3.执行

接着上一篇的加载,存成虚拟机要求的结构。那下一步就是代码的执行。

字节码已经加载进来,肯定是你new了它,或者其他情况触发了它的加载。

打比如new了它,也就加载、链接(验证、准备、解析)、初始化了。再接着就是实例化。实例化,这个过程是啥,就是执行。这过程涉及到啥?怎么样把字节码转化成机器码(设备可识别代码)?

虚拟机抽象定义,new这个操作就是一个栈帧,平时打印异常,记得不,e.printstack(异常打印的就是每个栈帧)。那其实就是一个一个的单元。按方法设计。理解每个方法,那就是理解全部。

方法里面又是怎么玩?二进制文件(字节码)那会,又栈的深度,局部变量个数,linetablename(源代码和字节码的对应关系),基本就说出来了。局部变量表(最小单位slot槽),方法栈(存的也是即将要用的数值),程序计数器(代码执行到第几行,偏移地址),还有返回地址(执行完这个方法回到哪里去,肯定是别人调用了这方法才运行啊);

由上面图片,看到main方法,显示

先创建一个对象,并将其引用值(对应堆里面的首地址)存到栈顶,

取栈顶值,并把它返回给栈顶

invokespecial虚拟机里方法调用指令,这个是调用构造函数,编译器就存储了指定的类与方法描述符

以上就new XiaoQiang()

把常量推送至栈顶

虚函数调用,这里是静态绑定,编译器就识别setName("XXXXXx")

返回

上面讲了这么多。就是方法与方法直接的调用,助记符的运行,还有很多概念没涉及到。

比如

1、局部变量表,这里除了this,没有其他局部变量表,故local:1;其他比如助记符isotre_1就是把栈顶常量存入局部变量表。

2、方法调用指令invokespecial(构造),invokeinterface(接口),invokeviture(重写重载,常规的也是),invokestatic(静态)

新增invokedynamic,调用了methodhandler,方法的归属交给代码编写者决定。

3、方法绑定,编译期确定,运行期确定,代码敲写确定

编译器确定通过类符号和方法符号,及描述符号确定

运行期确定,通过优化手段方法表,也就是每个方法的索引;

以上的每一行助记符都是我自己大脑识别,机器呢?

虚拟机有两种办法,解释执行和编译执行;解释把字节码一行一行的code解释成机器码;编译执行,把字节码统统一次性编译成机器码。虚拟机采用了结合两种方式的优劣,一起干。经常性执行代码,直接编译成机器码。不经常用的,解释执行。解释执行,可以结合运行时信息,灵活优化。怎么区分经常性执行与非经常性识别呢?专业术语,热点代码,常用计数方式识别。

编译器好几个。不同编译器优劣不同。有注重启动快速,运行消峰等。

猜你喜欢

转载自blog.csdn.net/huangddy/article/details/84262775