2014.7.23 内存分析_栈_堆_栈帧

来源:互联网 发布:iphone库存软件 编辑:程序博客网 时间:2024/05/22 10:41
摘要 关于内存分析的一个简单的过程。

程序的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
publicclassPoint{
    intx;
    inty;
    publicPoint(intx,inty){
        this.x=x;
        this.y=y;
    }
     
    publicstaticvoidmain(String[] args){
        inta=4;
        Point p1 =newPoint(3,4);
        Point p2 = p1;
        p1.x =30;
        System.out.println(p2.x);
    }
}

堆和栈。


栈(stack):

1.    内存是连续的空间。整个stack空间大小是确定的。

2.    存放局部变量

3.    存放特点:先进后出,后进先出。

 

堆(heap):

1.    是不连续的空间。

2.    存放创建的对象。


代码执行步骤分析

参照下面的截图分析。

首先,这段代码被执行的时候

第一步要加载类信息,加载Point类信息;把Point类的信息放在堆里面。Point类的信息就是public class Point下的代码,main方法也要包含在内,逻辑上main方法不属于Point类,但物理上main方法是属于Point类的。(名亡实存,大概可以用这么一个词来解释)。

第二步就是运行main方法了,方法运行时放在栈帧里面。所以先将main方法放入栈帧里,按代码顺序执行。1. int a = 4; 2.Point p1=new point(3,4); 又出现了一个方法,所以此时开辟一个新的栈帧,并把这个方法进栈。(ps:此时p1的地址默认为null)。

第三步是Point方法的进栈,也即构造器的进栈。Point方法读入x=3,y=4,同时执行int x;int y;    在堆里面创建一个对象,对象的属性有两个,x和y,都默认为0;假设这个对象的地址为010203;那么this的地址也就为010203(因为this指向的地址原本就是这个对象的地址)。

第四步,接着按顺序执行的方式执行构造器,即this.x=x;this.y=y;x按照地址找到this.x并将值赋给this.x,y同样按照地址找到this.y并将值赋给this.y,上一步在堆里创建的对象的值就改变了,堆里的x变为3,堆里的y变为4。

第五步,执行完毕,将构造器出栈,此时,程序会自动的把this的地址return给p1;那么p1的地址就变成了010203;

第六步,Point p2=p1;p1.x=30;System.out.println(p2.x);顺序执行这些语句,第一句p2的地址也变为了010203,第二句p1指向的x的值变为了30;即010203中的x变为了30;第三句,打印p2中的x,按照p2的地址,找到了010203中的x为30,将之打印出来。程序执行完毕,main方法出栈。

截图

0 0