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

Java中的栈内存和堆内存

时间:2014-12-19 21:52:51      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:

为什么我们常说基本类型传递的是具体的值,而对象传递的是对象的内存地址呢。要搞清楚这个问题就要搞清楚栈内存与堆内存。

   java的内存分为栈内存和堆内存,两者的作用是不同的,我们可以简单的理解如下:

   当我们创建一个java基本类型的变量时,只会用到栈内存而不会用到堆内存,栈内存中所存储的内容就是基本类型的值。

  int a = 3;
  int b = 3;

  执行第一行 int a = 3;时,JVM先会创建一个变量为a的引用,然后在栈内存中查找是否已经存在3这个值,没有找到,就会在栈内存中开辟一片区域存储3,然后将a指向存储3的位置。接着执行第二行int b=3;时也是先在栈内存中查找是否已经存在3这个值,是可以找到的,这时就将变量b的引用也指向存储3的位置。

  当我们用new来创建一个非基本类型的对象时,就不仅要用到栈内存还要用到堆内存。

  例如,Student s=new Student();

  也会先在栈内存中开辟一块内存,用s指向这块内存,但这时栈内存存储的不是new Student(),而只是一个内存地址,这个内存地址就是在堆内存中存储new Student()的那块内存的首地址。

  有了上面的概念,就可以解决一些简单的问题了。

  第一个,我们都知道比较字符串的内容要用到equals(),而不是==,原因是什么呢

  String s1=new String(“abc”);

  String s2=new String(“abc”);

  s1==s2 的结果是false,原因很简单,因为第一行和第二行都用到了new来产生新的对象,这两个对象在堆内存中的首地址肯定是不同的,那么s1所指向的栈内存中的内容与s2所指向的栈内存中的内容肯定是不同的,而==

比较的是栈内存,这时肯定是不相等的。

  而equals方法我们可以理解为比较的是堆内存中的内容,由于两个堆内存中的内容都是abc,则必然是相等的。

  第二个,把上面的稍微换一下

  String s1=“abc”;

  String s2=“abc”;

  这时s1==s2,因为没有new,也就没分配堆内存,都是用的是栈内存,在执行第二行时,栈内存中已经存在了abc,则s2直接指向这个地址就可以了,所以会有s1==s2。

  第三个,执行 String s1=“hello”;s1=s1+“world”的结果是怎样的呢

  执行第一句时,会在栈内存中分配一块内存存储hello,执行第二句时,会分配一块新的内存存储hello world,而这时的s1指向的不再是hello的那块内存而是hello world的那块内存了。存储hello 的那块内存将会被垃圾回收器所回收。

  第四个,我们常说复制基本类型时传递的是具体的值,而复制对象时传递的是对象的内存地址,这时候如果将栈内存和堆内存理解了,就可以明白是为什么了。

补充:

String a="abc"; 
String b="abc"; 
String c=new String("abc"); 
String d=c.intern(); 

因为引用变量c指向堆内存的地址;但是intern(); 却在栈中开辟了一块内存;其实c.intern(); 执行时,在栈内存中发现存在对象“abc”,所以直接将指针指向“abc”,这样 a == d, b==d 结果为true;

Java中的栈内存和堆内存

标签:

原文地址:http://www.cnblogs.com/zouzls/p/4174721.html

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