JVM撮要-指令集介绍03
JVM摘要--指令集介绍03【题外话】只要学过编译原理,计算机组成类似的课程的,就不会觉得JVM的字节码太难理解。
JVM摘要--指令集介绍03
【题外话】只要学过编译原理,计算机组成类似的课程的,就不会觉得JVM的字节码太难理解。有兴趣的人,只要边看书,边写几个例子后,再javap一下慢慢看几个就大概心里有数了,其实学习JVM的东西,主要是为了让自己对它的运行方式多一些了解,在实际编程过程中心里有个概念,有些特性的底层实现心里有数就行。
毕竟在大多数编程中,JVM的知识不会直接的影响到你的编程思路,但会潜移默化的让你绕过一些潜在的风险或者障碍。
下面稍微介绍两个概念:接收参数 和 方法调用
接收参数
实例方法(非静态方法)和类方法(静态方法)的实现是略有不同的,因为当调用一个实例方法时,首先会将该类的自身的实例的引用作为第0个参数放置在局部变量表中,然后才在局部变量表的第1到N的位置上放置参数(如果有参数, N是参数个数)。
而静态方法不需要传递自身实例的应用,所以参数是从第0个开始存放。
(要注意long和double所占局部变量的大小为2)
大家可以用下面这两个例子做下测试
//example_1
STEP2: 将常量12和13分别push到操作数栈
STEP3: 调用addTwo方法,在调用该方法时,JVM创建一个新的frame,并将自己实例的指针,以及参数12和13传给新的Frame中的局部变量表。
注:每条invokevirtual指令都会带有一个表示索引的参数,如图中的#2, 通过该标识,JVM可以通过查找常量池找到方法addTwo的符号引用,该符号引用可以提供方法所在对象的类型的内部二进制名称、方法名称和方法描述符
STEP4: 目前的操作都针对Frame_addTwo中的操作数栈,如图,从局部变量表加载位置的变量和位置2的变量,即12和13
STEP5: 求和运算,将结果25压入到操作数栈中
STEP6: addTwo()方法返回,将其栈顶的值(即25)push到其调用者(即add12And13)方法所在的操作数栈,并且在该调用完成后,addTwo所拥有的frame就被删除掉。
STEP7: add12And13()方法返回,将其栈顶的值(即25)push到其调用者所在的操作数栈,并且在该调用完成后,add12And13所拥有的frame就被删除掉。