码迷,mamicode.com
首页 > 编程语言 > 详细

菜鸟学Java(二十三)——Java内存分析

时间:2014-11-30 15:23:33      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   ar   color   os   sp   java   on   

我们常说的Java内存主要分为四大块(寄存器不在考虑之内,我们无法用代码来操控它):stack(栈)、heap(堆)、data segment(数据区)、code segment(代码区)。它们的主要用途如下图所示:


bubuko.com,布布扣



而在上面四个当中,我们经常谈论的是右边那两个家伙——stack和heap。今天我们就来聊聊Java代码在运行的过程中,在stack和heap中到底是什么样子的吧。


我们先看下面一段代码:

 

    public static void main(String[] args) {
        TestReference testReference = new TestReference();
        int age = 1;
        Person xiaoqiang = new Person("小强", 21);
        Person xiaoming = new Person("小明", 22);
        
        testReference.selfPlus(age);
        System.out.println("age经过selfPlus方法的处理后为:" + age);
        
        testReference.changeName(xiaoqiang);
        System.out.println("小强经过changeName方法的处理后的名字为:" + xiaoqiang.getName());
        
        testReference.changeAge(xiaoming);
        System.out.println("小明经过changeAge方法的处理后的年龄为:" + xiaoming.getAge());
        
    }
    
    public void selfPlus(int i) {
        i = i + 1;
    }
    
    public void changeName(Person person) {
        person = new Person("小刚");
    }
    
    public void changeAge(Person person) {
        person.setAge(25);
    }

 



执行完以上代码,会打印出什么内容呢?如果你Java基础还可以,那么很容易就能知道会输出什么内容,想要知道以上代码会打印什么内容,需要你明白Java代码在stack和heap中是怎么工作的。下面我们结合几张图来看看:

 

        int i = 1;
        Person xiaoqiang = new Person("小强", 21);
        Person xiaoming = new Person("小明", 22);

 


当我们执行完上面三行代码时,内存中的情况如下图所示:

bubuko.com,布布扣


我们知道stack是用来存放变量的,所以age、xiaoqiang和xiaoming三个变量会被存放到stack里,而age又是int类型,所以它的值也会被存放在stack里面。xiaoqiang和xiaoming为Person类型的引用变量,所以stack只会存放它们的一个引用,也就是对应对象的内存地址,而它们真正的内容被存放在了heap里面。


当执行到testReference.selfPlus(i);时,selfPlus(int i)方法被调用,此时会在stack中为形参I开辟一块内存空间,并将其值设置为1,此时内存中的情况如下:

bubuko.com,布布扣

因为调用selfPlus(int i)方法时,将age作为形参传递给该方法,相当于将age的值复制一份给i,所以现在i的值为1,接着执行i = i + 1;此时i的值被修改为2,如图:

bubuko.com,布布扣

此时被修改的只是age的副本,而并非age本身,所以age仍为1,当selfPlus(int i)方法被执行完,i被销毁,age不变。接下来看xiaoqiang,当调用changeName(Person person)方法时,会在stack中为person分配一块空间,里面存放的是xiaoqiang指向的地址,如图:

bubuko.com,布布扣

然后执行到person = new Person("小刚");时,由于又new了一个Person对象,所以在堆中会新建一个person,姓名叫小刚,并且会将person执行小刚的地址,如图:

bubuko.com,布布扣

此时,person指向的对象由小强变成了小刚,但是xiaoqiang所指向的对象仍然是小强,并没有发生任何变化。当changeName方法执行完以后,person被销毁,而小刚也会因为没有任何对象对其进行引用,随后被垃圾回收器回收掉。


下面到了最后一个方法了,当执行testReference.changeAge(xiaoming);时,调用changeAge(Person person)方法,同样会在stack中为person分配一块空间,这次里面存放的是xiaoming对应的内存地址,如图:

bubuko.com,布布扣


然后执行person.setAge(25);,此时person指向的对象为小明,所以在执行setAge方法时,修改的就是heap中小明的属性值,此时小明的年龄被修改为25,。方法执行完毕,person被销毁,内存中最终结果如下:

bubuko.com,布布扣

内存中的最终情况就如上图所示,当然当main方法执行完以后,之前创建的所有对象都会被销毁。OK,每天上班做项目的你是不是把一些基础的东西忘了呢?如果是的话就赶快来补一补吧,好处还是很多的。



菜鸟学Java(二十三)——Java内存分析

标签:style   blog   http   ar   color   os   sp   java   on   

原文地址:http://www.cnblogs.com/liushuijinger/p/4132275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!