Java内存分析
来源:互联网 发布:python赚外快 编辑:程序博客网 时间:2024/04/27 23:00
我们常说的Java内存主要分为四大块(寄存器不在考虑之内,我们无法用代码来操控它):stack(栈)、heap(堆)、data segment(数据区)、code segment(代码区)。它们的主要用途如下图所示:
而在上面四个当中,我们经常谈论的是右边那两个家伙——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);
当我们执行完上面三行代码时,内存中的情况如下图所示:
我们知道stack是用来存放变量的,所以age、xiaoqiang和xiaoming三个变量会被存放到stack里,而age又是int类型,所以它的值也会被存放在stack里面。xiaoqiang和xiaoming为Person类型的引用变量,所以stack只会存放它们的一个引用,也就是对应对象的内存地址,而它们真正的内容被存放在了heap里面。
当执行到testReference.selfPlus(i);时,selfPlus(int i)方法被调用,此时会在stack中为形参I开辟一块内存空间,并将其值设置为1,此时内存中的情况如下:
因为调用selfPlus(int i)方法时,将age作为形参传递给该方法,相当于将age的值复制一份给i,所以现在i的值为1,接着执行i = i + 1;此时i的值被修改为2,如图:
此时被修改的只是age的副本,而并非age本身,所以age仍为1,当selfPlus(int i)方法被执行完,i被销毁,age不变。接下来看xiaoqiang,当调用changeName(Person person)方法时,会在stack中为person分配一块空间,里面存放的是xiaoqiang指向的地址,如图:
然后执行到person = new Person("小刚");时,由于又new了一个Person对象,所以在堆中会新建一个person,姓名叫小刚,并且会将person执行小刚的地址,如图:
此时,person指向的对象由小强变成了小刚,但是xiaoqiang所指向的对象仍然是小强,并没有发生任何变化。当changeName方法执行完以后,person被销毁,而小刚也会因为没有任何对象对其进行引用,随后被垃圾回收器回收掉。
下面到了最后一个方法了,当执行testReference.changeAge(xiaoming);时,调用changeAge(Person person)方法,同样会在stack中为person分配一块空间,这次里面存放的是xiaoming对应的内存地址,如图:
然后执行person.setAge(25);,此时person指向的对象为小明,所以在执行setAge方法时,修改的就是heap中小明的属性值,此时小明的年龄被修改为25,。方法执行完毕,person被销毁,内存中最终结果如下:
内存中的最终情况就如上图所示,当然当main方法执行完以后,之前创建的所有对象都会被销毁。OK,每天上班做项目的你是不是把一些基础的东西忘了呢?如果是的话就赶快来补一补吧,好处还是很多的。
【本文转至】:http://blog.csdn.net/liushuijinger/article/details/41605387
- Java的内存分析
- Java内存分析图
- Java内存分析小节
- Java 程序内存分析
- Java 程序内存分析
- Java 内存溢出分析
- java内存分析
- java内存分析
- java内存分析【精辟】
- JAVA内存分析笔记
- java内存模型分析
- Java内存分析
- java的内存分析
- JAVA基础--内存分析
- java内存分析
- Java内存管理分析
- Java内存泄漏分析
- java内存原型分析
- 使用fiddler做web的压力测试
- iOS AppStore评价
- linux内核设计与实现读书笔记——内核同步
- 第六章思维导图
- JSON 之FastJson解析
- Java内存分析
- 第十四周项目一
- linux 下的svn服务器的配置与访问
- 【软文发布】电子商城购物系统网站建设
- HTML:表格
- lua调用c++
- Linux 硬链接与软链接的区别
- FragmentPagerAdapter 和FragmentStatePagerAdapter
- 解决spring3 mvc中乱码的问题。