现在的位置: 首页 > 综合 > 正文

堆和栈的区别

2013年10月14日 ⁄ 综合 ⁄ 共 1512字 ⁄ 字号 评论关闭

4.2 容易被搞晕的--堆和栈

由于"堆"和"栈"这两个概念是看不见摸不着的东西,让很多程序员都整不明白是怎么回事,其实这两个概念也没有什么好研究的,因为堆和栈程序员根本没有办法控制其具体内容。

我们只需要了解一点,栈与堆都是Java用来在内存中存放数据的地方就行了。然后再弄清楚这两个概念分别对应这程序开发的什么操作,以及堆和栈的区别即可。

4.2.1 堆--用new建立,垃圾自动回收负责回收

1、堆是一个"运行时"数据区,类实例化的对象就是从堆上去分配空间的;

2、在堆上分配空间是通过"new"等指令建立的;

3、Java针对堆的操作和C++的区别就是,Java不需要在空间不用的时候来显式的释放;

4、Java的堆是由Java的垃圾回收机制来负责处理的,堆是动态分配内存大小,垃圾收集器可以自动回收不再使用的内存空间。

5、但缺点是,因为在运行时动态分配内存,所以内存的存取速度较慢。

例如:

String str = new String("abc"); 
就是在堆上开辟的空间来存放String的对象。

4.2.2 栈--存放基本数据类型,速度快

1、栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄;

2、栈的存取速度比堆要快;

3、栈数据可以共享;

4、栈的数据大小与生存期必须是确定的,缺乏灵活性。

例如:

int a = 3; 
就是在堆上开辟的空间来存放String的对象。

4.2.3 何谓栈的"数据共享"

栈其中一个特性就是"数据共享",那么什么是"数据共享"呢?

我们这里面所说的数据共享,并不是由程序员来控制的,而是JVM来控制的,指的是是系统自动处理的方式。

比如定义两个变量:

int a = 5;
int b = 5;
这两个变量所指向的栈上的空间地址是同一个,这就是所谓的"数据共享"。

它的工作方式是这样的:

JVM处理int a = 5,首先在栈上创建一个变量为a的引用,然后去查找栈上是否还有5这个值,如果没有找到,那么就将5存放进来,然后将a指向5。

接着处理int b = 5,在创建完b的引用后,因为在栈中已经有5这个值,便将b直接指向5。

于是,就出现了a与b同时指向5的内存地址的情况。

4.2.4 实例化对象的两种方法

对于String这个类来说它可以用两种方法进行建立:

String s = new String("asdf"); 

String s = "asdf"; 
用这两个形式创建的对象是不同的,第一种是用new()来创建对象的,它是在堆上开辟空间,每调用一次都会在堆上创建一个新的对象。

而第二种的创建方法则是先在栈上创建一个String类的对象引用,然后再去查找栈中有没有存放"asdf",如果没有,则将"asdf"存放进栈,并让str指向"asdf",如果已经有"asdf" 则直接把str指向"abc"。

我们在比较两个String是否相等时,一定是用"equals()"方法,而当测试两个包装类的引用是否指向同一个对象时,我们应该用"= ="。

因此,我们可以通过"= ="判断是否相等来验证栈上面的数据共享的问题。

例1:

String s1 = "asdf"; 
String s2 = "asdf"; 
System.out.println(s1==s2); 
该程序的运行结果是,"true",那么这说明"s1"和"s2"都是指向同一个对象的。

例2:

String s1 =new String ("asdf"); 
String s2 =new String ("asdf"); 
System.out.println(s1==s2);

该程序的运行结果是,"false",这说明用new的方式是生成的对象,每个对象都指向不同的地方。

抱歉!评论已关闭.