A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 占琳 中级黑马   /  2012-10-22 17:31  /  1330 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

请问什么是栈 什么是堆 ,当我实例化一个对象的时候 他在栈里还是堆里

6 个回复

倒序浏览
栈内存  用于存储局部变量的,数据一用完就会自动释放,就是没了。。
堆内存  数组和对象通过new建立的实体都在这里。

栈内存中的变量没有默认初始化值;堆内存的变量有默认初始化值,比如int型的是0,double型的是0.0,boolean型的是false

对象建立的实体在堆内存中

评分

参与人数 1技术分 +1 收起 理由
谭立文 + 1

查看全部评分

回复 使用道具 举报
栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方

栈的存储空间较小,会自动出栈,存储速度快,栈中主要存放一些基本类 型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
堆可以动态分配内存大小,由垃圾回收器来处理他的内存,处理速度慢

回复 使用道具 举报
共同点:
都是java用来在存储器中存放数据的地方。
区别:
栈:主要用于存取基本数据类型(也叫内置类)和对象引用。优点:速度比较快,仅将于寄存器;数据可以共享。缺点,存取的大小与生存期必须明确,缺乏灵活性。
堆:主要用于存储对象 ,凡是new出来的对象都在内存堆中。 优点:可以动态的分配内存大小,生存期也不必明确,因为有jvm会自动回收,缺点:运行时需要分配内存,存取速度慢。
回复 使用道具 举报
二者之间的区别和联系
1.栈:位于通用的 RAM (随机访问存储器)区域,但可通过它的“堆栈指针”获得处理的直接支持。堆  栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存 方式,仅次于寄存器。创建程序时,Java 编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活 性,所以尽管有些Java 数据要保存在堆栈里——特别是对象引用,但Java 对象并不放到其中。
2. 堆:一种通用的内存池(也在 RAM 区域),其中保存了Java 对象。和栈不同,“堆”最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要 在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可 。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!

实例化一个对象时,如 String  str = "abc";对象引用(str)存放在栈里,对象内容(abc)存放在堆内存里。
回复 使用道具 举报
当一个应用程序启动时(这里假定为某个.exe程序),系统会分配一块内存空间给它,并另外再分配一个谓之“栈”的空间,应用程序在需要时,会在这个“栈”里面分配空间,比如看到 int x = 5;时,就在这个“栈”里面分配一个int数据的空间(注意,“栈”在启动.exe程序时,其在内存中的位置和大小就分配好了,如果不够用我不知道怎么办),非引用类型都是这样分配空间的,即不是用new来分配的东东,都在这个“栈”里这么分配了;

与之相对应的就是“堆”了(可能也叫堆栈,不确定,水平有限),那么什么是“堆”呢?
“堆”,就是内存空间,就是那些不属于任何.exe程序启动时被分配的空间(包括程序空间和“栈”的空间),换句话说,比如你有256MB内存,启动一个.exe程序,就会分配一定的空间(包括程序空间和一个“栈”),假设是10MB,那么还有246MB,这些就都是“堆”了,你在应用程序中new一个实例,就是在这246MB里,分配一定的空间给这个应用程序用了。(这里是打个比方,你要分配>256MB的空间也行,操作系统会通过虚拟内存技术来满足你的需求)

总结一下,“栈”和“堆”都是内存空间
“栈”随应用程序启动而分配,其在内存中的位置和大小,一开始就分配好了;
“堆”不随应用程序启动而分配,你需要(new类实例)时才分配,其在内存中的位置是不确定的,大小就是类的大小了;

再多说一下,比如有一个Test类,程序中代码如下:
Test MyTest = new Test();

MyTest实例在“堆”中分配好空间,其在内存中的首地址,返回给程序使用,这是一个4个字节数值,它被赋给MyTest这个“变量”,MyTest这个“变量”就是一个引用,它的长度为4个字节,正好装下返回的地址值,那么,既然MyTest这个“变量”本身也是有大小的(4字节),那么它是在哪里分配的呢?答案是“栈”,MyTest这个“变量”是在“栈”中。
也就是说,“栈”中分配一个4字节的空间,这个空间里记录一个4字节长度的数值,这个数值是一个内存地址,指向“堆”空间(内存)中的一个单元,以此单元为首地址,这里记录着一个类实例。

回复 使用道具 举报
1 、栈区由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。用完的数据自动清除。
2 、堆区存储对象,如new创建出来的对象,有垃圾回收机制。
楼主实例化一个对象,如 Person p = new Person();
这个对象的内容存在堆区,对象的名字p存在栈区。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马