线程栈-当前栈帧

假如运行以下Math.hava类

package com.cjc.classload;

public class Math {
    public static final Integer COUNTAGE = 666;

    public static User user = null;

    public int count(){ //一个方法对应一个当前栈帧
        int a = 1;
        int b = 2;
        int c = (a + b)*10;
        return c;
    }

    public static void main(String[] args){
        Math math = new Math();
        math.count();
        user  = new User();

    }
}

那么栈中是如何运作的。

首先将Math.class文件反汇编并存放在Math.txt文件中(javap -c Math.class > Math.txt),可以看到count()方法的代码执行过程如下

 接下来通过查询jvm指令(具体百度一下就可以),这里说一下代码中几句的意思:

  iconst_1意思是将int类型常量1压入栈,

  istore_1意思是将int类型值存入局部变量1,

  iload_1意思是从局部变量1中装载int类型值,

  iadd意思是执行int类型的加法,

  bipush意思是将常数放入操作数栈,

  imul意思是执行int类型的乘法。

接下来一句一句来演示:

iconst_1:将int类型常量1压入操作数栈

 istore_1:在局部变量表中开辟空间保存a变量,再将操作数栈中的1出栈并赋给a

 iconst_2:将int类型常量2压入操作数栈

 istore_2:在局部变量表中开辟空间保存b变量,再将操作数栈中的2出栈并赋给b

 iload_1:从局部变量1也就是a变量装载1入操作数栈

 iload_2:从局部变量2也就是b变量装载2入操作数栈

 iadd:从栈顶弹出两个int类型的数进行相加操作,结果再入栈

 bipush:将常量值10入栈

 imul:从栈顶弹出两个int类型的值进行乘法操作,结果再入栈

 istore_3:在局部变量表中开辟空间保存c变量,再将操作数栈中的30出栈并赋给c

 iload_3:从局部变量3也就是c变量装载30入操作数栈

 ireturn:将操作数栈中的int类型的数30返回

 不是结尾的总结:

  1、堆和方法区是线程共享的;栈、本地方法栈、程序计数器是线程私有的。

  2、栈的默认内存大小是1M。可以通过-Xss+大小设置,如设置为-Xss128k

  

   3、栈中局部变量表若存储的是引用类型变量如对象等,则存的是地址值,指向堆中的对象。

  4、操作数栈:就是存放接下来要被操作的数,可以理解为临时存放区。

  5、动态链接:在程序运行期间将符号引用替换为直接引用的过程就是动态链接。

  6、方法出口:指向方法结束后接下来要执行的代码。

  

学习没有一蹴而就,放下急躁,一步一步扎实前进
原文地址:https://www.cnblogs.com/jpxjx/p/12539919.html