黑马程序员技术交流社区

标题: 关于堆和栈的问题 [打印本页]

作者: 刘奇    时间: 2012-7-24 15:44
标题: 关于堆和栈的问题
本帖最后由 刘奇 于 2012-7-24 22:32 编辑

我的理解是堆和栈都是容器,栈保存的是一些动态的变量和程序的返回地址信息等内容,堆保存的是引用的变量信息。这样理解对吗?还有以前在面试的时候被问道,为什么栈会爆,而堆却不会呢?
作者: 姬仁贵    时间: 2012-7-24 16:04

堆栈:函数的参数值,局部变量等,自动清除!
堆:静态变量和成员变量,new得到的变量,都存放在堆中!
局部变量à栈中;
方法参数à栈中;
引用变量à栈中;
常量à栈中;
静态变量à堆中(常量池àJVM运行时首先为其开辟空间,位置不变,程序运行结束时空间释放);
静态方法à堆中(静态存储à JVM运行时首先为其开辟空间,位置不变,程序运行结束时空间释放);
成员方法ànew的时候存储在堆中;
成员变量ànew的时候存储在堆中;
new的字符串存放在JVM的地址池中,地址池也是位于栈中!




栈:位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。


堆:一种通用性的内存池(也存在于RAM中),用于存放所有的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代码。用堆进行存储分配比用堆栈进行存储存储需要更多的时间。

作者: 黑马-李勇    时间: 2012-7-24 16:39
栈指针向下移动,堆指针向上移动。
http://wenku.baidu.com/view/a2509bd528ea81c758f578d1.html
我虽然没看懂程序,但可以理解楼主的问题了。{:soso_e113:}
作者: 李菁    时间: 2012-7-24 19:02
java中的堆是一个运行时数据区,它是在运行时动态分配内存。例如定义一个对象时,虚拟机会自动从堆中分配一块空间存储对象,此对象的释放也不需要程序代码控制,因为堆是有垃圾回收控制的。编译器不需要知道此对象的生命周期,java的垃圾收集器会自动收走不再使用的对象或数据
栈在java中主要存放一些基本类型的变量和对象。存在栈中的数据必须确定大小和生命周期,正是因为这个原因此类数据缺乏灵活性。栈的存储速度比堆快。
栈的一个重要特性是存在栈中的数据可以共享。举个例子:
int a=2;
int b=2;
编译器先处理int a=2,先在栈中创建一个变量叫a的引用,然后找栈中有没有2这个值,如果没有,把2存进栈中,将a指向2.
再处理int b=2,在栈中创建变量为b的引用,查找有无2这个值,在栈中找到这个值,把b直接指向2。
这时a和b同时指向2,这就是数据共享的情况
作者: 乐峰    时间: 2012-7-24 19:55
Java把内存划分成两种:一种是栈内存,一种是堆内存。

在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。

当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

堆内存用来存放由new创建的对象和数组。

在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。

引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

作者: 王楠    时间: 2012-7-24 23:18
堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。要点:堆,顺序随意。栈,后进先出




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2