栈内存状态变化概述

【参考链接】

实例分析Java代码运行时内存布局http://blog.csdn.net/wangyy130/article/details/52100907

运行时数据区http://blog.csdn.net/u012440687/article/details/52021393

 

1、栈帧的顺序画反了

2这里都是通过参数进行数据传递,主要是在操作局部变量表,如果通过对象的成员变量进行传递,则是操作堆内存

 

通过如下一个实例,研究一下运行时各内存区域的状态变化,主要是为了讲解,当方法调用完成后,栈内存就会自动被回收

TestB类有一个method1()方法,接收两个参数返回他们的和

 Java Code 

1
2
3
4
5
6
7
 

 

package com.shadowfaxghh.test;

public class TestB {
    public int method1(int arg1, int arg2){
        return arg1+arg2;
    }
}

 

TestA类有一个方法method1(),会调用TestBmethod1()

 Java Code 

1
2
3
4
5
6
7
8
9
 

 

package com.shadowfaxghh.test;

public class TestA {
    public int method1(){
        TestB v1=new TestB();
        return v1.method1(100, 200);
    }
}

 

Main类作为执行入口

 Java Code 

1
2
3
4
5
6
7
8
9
10
 

 

package com.shadowfaxghh.test;

public class Main {

    public static void main(String[] args) {
        TestA v1=new TestA();
        int v2 = v1.method1();
        System.out.println(v2);
    }
}

 

 

首先运行的时候要去加载Main类,在方法区生成类Main的运行时数据结构,在堆上生成其Class对象

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\1.png

接着运行主线程,执行其中的main()方法,会往中压入一个main()方法的栈帧。

因为是静态方法,所以没有隐藏的this局部变量

局部变量表中一共有3个局部变量其中第0个局部变量作为形参其内容已经确定了。

操作数栈中目前还是空的。

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\2.png

接下来执行main()方法的字节码指令

去加载TestA

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\3.png

然后在堆上创建一个新的TestA对象,并将其引用压入操作数栈

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\4.png

然后复制一份栈顶元素,弹出栈顶元素,调用构造函数,并压入返回值,因此时返回值为空,故没有压入

然后弹出栈顶元素,将其赋值给第1个局部变量

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\5.png

 

将第1个局部变量压入操作数栈,弹出栈顶元素,并调用其method1()方法

会往栈中压入一个method1()方法的栈帧

局部变量表中有3个局部变量,第0个局部变量为TestA对象的引用

 

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\6.png

 

接下来执行TestAmethod1()方法

同样是加载类TestB,复制一份引用,弹出栈顶元素,并调用其构造函数,再弹出栈顶元素将其赋值给1个局部变量

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\7.png

 

将第1个局部变量压入操作数栈

100200压入操作数栈

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\8.png

弹出栈顶元素,调用TestB对象的method1()方法

向栈中压入一个method1()方法的栈帧

局部变量表中3个局部变量,其中第1个局部变量作为形式参数为100,第2个局部变量作为形式参数为200

 

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\9.png

 

接下来执行TestBmethod1()方法

将第1个、第2个局部变量压入操作数栈,弹出栈顶元素,进行相加操作,并将结果压入操作数栈

 

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\10.png

 

 

TestBmethod1()方法返回,将TestBmethod1()的栈顶元素弹出并压入到调用方法的操作数栈清除TestBmethod1()方法的栈帧

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\11.png

 

回到TestAmethod1()方法中继续执行

调用return指令,将栈顶元素弹出并压入调用方法的操作数栈,清除TestAmethod1()方法的栈帧

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\12.png

 

此时已经没有引用指向堆中的TestB对象了,在进行下次堆内存垃圾回收,会回收掉它

 

回到Mainmain()方法中继续执行,弹出栈顶元素并赋值给第2个局部变量

 

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\13.png

 

然后获取静态成员变量System.out压入操作数栈将第2个局部变量压入操作数栈,弹出栈顶元素并调用println()方法,将返回结果压入操作数栈,没有结果故不压入

最后执行return返回

其中System的静态成员变量out,引用是在方法区的类System的运行时数据中,实例是在堆中。下图简略描述一下

D:\T\归纳整理(新)\2017-10-34 栈内存状态变化概述\vsdx\14.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值