1.bipush指令
当int取值-128~127时,JVM采用bipush指令将常量压入栈中
2.sipush指令
当int取值-32768~32767时,JVM采用sipush指令将常量压入栈中。
3.ldc指令
当int取值-2147483648~2147483647时,JVM采用ldc指令将常量压入栈中。
4.两个int类型相加指令iadd
本地变量表:
0 this
1 a
2 b
3 c
iload将a,b压栈
iadd将a和b相加
istore将结果指向变量表c
5.调用引用类型的方法
下面这个方法的执行流程是:当new一个对象的时候,
先在堆内存申请一块内存,地址压栈,这个时候对象是默认值;
dup复制地址 ,压栈,现在有两个地址,内存对象是默认值;
invokespecial调用init执行默认构造方法,对象赋初始值,出栈用掉一个地址;
astore1弹栈到方法变量表赋值给H;
aload1入栈;
invokevirtual调用本地方法m1;
6.返回值
区别在于invokevirtual是调用对象本地方法,
1:h.m1();方法直接结束,调用完毕直接return;
2:h.m1();方法调用结束有返回值需要pop弹栈;
3:h.m1();方法调用结束有返回值需要出栈然后赋值给本地变量表;
7.递归调用方法入栈出栈![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/61d61945486b76ecb243791a0d99e014.png)
每一个线程对应一个线程栈,每一个方法对应一个栈帧,递归调用每调用一次方法就会入栈,栈先进后出,调用一次进一次,符合条件的停止递归调用然后一级一级出栈;如果递归没有结束条件,一直递归调用,栈的深度是有限的,就会栈内存溢出异常。
8.invokestatic,invokespecial,invokeinterface,invokevirtual,invokedynamic
9.invokedynamic
lambda表达式或者反射或者其他动态语言scala kotlin,或者CGLib ASM,动态产生的class,会用到的指令。动态产生class字节码文件