JAVA内存浅析

原文地址: JAVA内存浅析(小天原创) 作者: 小天

时间很快,悄然间就来到了11月,不知不觉开学已经两个月了。算算看再有半年就毕业了,大学的美好生活即将离我远去,马上就要进入社会,有些许迷茫,有些许畏惧,有些许不舍又有些许期待,呵呵,难道这就是所谓的毕业综合症。

好了,言归正传,前几天在学习java在内存中是如何运行的,发现不少java初学者对此都不是很清楚,包括一些编程还可以的同学,偏偏不论是在面试,还是要考SCJP,java内存分析还是很重要的。在此,同样以一个初学者的身份分享一下我的思路,与大家共同探讨。

首先,无论你写一段什么样的代码,代码都是存储在硬盘中,使用时才通过内存调用。

  [转载]JAVA内存浅析(小天原创)

 

其次,存放数据的内存大致分为4块,分别是code代码块,static静态区,stack栈,heap堆。(其实还有文字常量区,这次暂不讨论)。在java我们写完一段代码,调用时代码时java虚拟机会把代码编译成.class文件,.class文件会存放在程序代码区也就是我所说的代码块。而后计算机开始从main一行行解读程序,main方法放在static静态区,这也就是为什么main方法要用static修饰的原因。

[转载]JAVA内存浅析(小天原创)

 

现在我们开始重点分析程序在堆栈里的存放,以两段简单代码为例。

1  packagecom.scjp.memory;

 

2  publicclass MainClient {

3    public static void main(String[] args) {

4       Student p=new Student(23,12345);

5       p.test();

6        System.out.println(p);

      // TODO Auto-generated method stub

7  }

8  }

9  packagecom.scjp.memory;

 

10  publicclass Student {

11  private int age;

12  private int number;

13  public Student(int age,int number){

14      this.age=age;

15      this.number=number;

16  }

17  public void test(){

18      System.out.println(this.age);

19      System.out.println(this.number);

20  }

21}

输出结果:

23

12345

com.scjp.memory.Student@1c78e57

真正算起来有效代码不到20行,我们结合图片对其进行内存分析。首先计算机从第3main方法开始读起,读到第4Student p=new Student(23,12345);时,系统在栈空间创建了个对象Pp指向堆空间里new出来的一个新的Student对象,该对象此时在堆空间中的有属性agenumber,方法test(){},还有this,此时该对象的初始值为age=0prower=0p其实就是该对象的内存逻辑地址,映射其内存物理地址(相当于c的指针)。

[转载]JAVA内存浅析(小天原创)

 

紧接着程序读到第4行小括号中内容时,程序跳转到第13行,程序将数值2312345传入Student中,public Student(int age,int number)agenumber俱为形参,注意:此时栈空间中age=23,number=12345,堆空间的age,number还是为0。通过第14,15行的this,(p指向this,this指向对象本身)将age与number的值传入堆空间中,此时堆空间的对象age=23,number=12345,而栈空间中的age与number被内存清除,这就是所谓的java中的垃圾回收机制,自动回收指针,释放内存,避免了c语言中指针忘记清空造成的内存溢出。通过这里也可以看出第11,12行的agenumber为全局变量而13行中的agenumber为局部变量,局部变量作用域至第16行的大括号而结束。好了,程序继续运行至16行后转回第5行,对象p调用test方法,程序转到17行,输出agenumber的值。紧接着程序转回第6行输出p,从运行结果可以看出输出的值就是一段内存地址。所以说p就是对象的内存逻辑地址。

[转载]JAVA内存浅析(小天原创)

    [转载]JAVA内存浅析(小天原创)
 

现在我们把代码改一下,将第14,15行中的this.去掉改成age=agenumber=number。此时输出的最终结果是什么?答案显而易见,数值传入栈中的agenumber后,因为没有this,值没有传入堆空间内,16行后栈空间的agenumber被内存清除,而堆空间的agenumber还是为0。所以打印出来的值为0

这就是最简单的java内存分析,以后我还会逐步分析更复杂的java程序,希望能对大家有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值