黑马程序员技术交流社区

标题: 堆内存和栈内存,求助 [打印本页]

作者: 熊志伟    时间: 2012-10-21 20:35
标题: 堆内存和栈内存,求助
本帖最后由 熊志伟 于 2012-10-22 19:18 编辑

毕老师在基础视频里面提到了堆内存和栈内存,他们具体区别是什么?搜了资料看了下但还是比较模糊,麻烦哪位大虾用简单语言解释下
作者: 占琳    时间: 2012-10-21 20:47
堆内存就是你用new 修饰符创建的内容会在堆内存中开辟一段空间,存放new出来的对象,比如 new String("ABC"), 就在堆内存空间分配了一块空间,它的内容是"ABC",而栈内存是你存放引用变量的地方,比如String a = new String("ABC")中 a这个变量就是在栈内存空间中分配了一块空间,它指向堆内存中内容为"ABC"的地址
作者: 黑马李勇    时间: 2012-10-21 20:58
我是这样理解不知道可不可以帮到你,栈内存中存储的是可以直接调用的变量,比如说基本类型,然后堆内存中存储的是那些间接调用的变量,例如数组、类这些复合类型,这些变量在栈内存中存储地址,然后地址指向堆内存中实际存储的值。
作者: 王龙    时间: 2012-10-21 21:08
这也是我的问题嘿嘿
作者: 王健宇    时间: 2012-10-21 21:16
我是这么理解的:栈内存保存的是名称相当于key,而堆内存保存的是具体内容相当于value,希望对你有所帮助。
作者: 李铁    时间: 2012-10-21 21:24
共同点:
都是java用来在存储器中存放数据的地方。
区别:
栈:主要用于存取基本数据类型(也叫内置类)和对象引用。优点:速度比较快,仅将于寄存器;数据可以共享。缺点,存取的大小与生存期必须明确,缺乏灵活性。
堆:主要用于存储对象 ; 优点:可以动态的分配内存大小,生存期也不必明确,因为有jvm会自动回收,缺点:运行时需要分配内存,存取速度慢。
作者: 黄小贝    时间: 2012-10-21 21:30
本帖最后由 黄小贝 于 2012-10-21 21:31 编辑


作者: 梁枝武    时间: 2012-10-21 21:41
1,栈内存 存放局部变量 引用变量等 这些变量在没有显式初始化的情况下是没有默认初始值的,栈内存中变量,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,对应引用变量若不再指向任何对象实体则也会在内存中释放掉
2,堆内存用类存放对象实体,new操作产生的数据,如数组元素,非静态的成员变量等,这些变量如果没有显式赋初值,则系统添加默认初始值
堆内存中的变量在没有被任何引用变量所引用的话会变成垃圾,不会立马被清除掉,而是有内存的垃圾回收机制定时清理
作者: 鲁中需    时间: 2012-10-21 21:41
java编程思想里是这么说的,可以参考参考:
1.栈:位于通用的 RAM (随机访问存储器)区域,但可通过它的“堆栈指针”获得处理的直接支持。堆  栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存 方式,仅次于寄存器。创建程序时,Java 编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活 性,所以尽管有些Java 数据要保存在堆栈里——特别是对象引用,但Java 对象并不放到其中。
2. 堆:一种通用的内存池(也在 RAM 区域),其中保存了Java 对象。和栈不同,“堆”最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要 在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可 。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!

作者: 草上飞    时间: 2012-10-21 21:47
栈stack:是程序启动时候由程序留出的工作内存区     比如程序的局部变量,函数调用等都是从栈中获取,这个内存在需要的时候分配,不需要就释放     堆heap:是计算机空余的物理内存和硬盘空余空间的和.     但是它的获取不是自动的了,相比从栈中分配内存要慢些Top使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。 使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
作者: 张其辉    时间: 2012-10-21 22:38
栈内存:
      1、存储的都是局部变量;
      2、而且变量的作用域一旦结束,该变量就自动释放。
堆内存:
      1、凡是new建立的都在堆内存;
      2、每一个实体都有首地址值;
      3、堆内存中的每一个变量都有默认初始化值,根据类型不同而不同;
      4、有自己的特定的垃圾回收机制
作者: 刘学宾    时间: 2012-10-21 22:59
栈内存用来存放简单数据类型,引用数据类型的变量(值指向堆内存目标首地址)。但不存放对象内容。
而堆内存用来存放引用数据类型的实例,也就是对象的内容,并且存放时使用new关键字来创建对象。
希望对你有所帮助。
作者: ﹏゛心被伱牵    时间: 2012-10-22 09:06
Java把内存划分成两种:一种是栈内存,一种是堆内存。  在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。  当在一段代码块定义一个局部变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被释放。  
   
       堆内存用来存放由new创建的对象和数组。  在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。  在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。  引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。 栈与堆都是Java用来在内存中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

       Java的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(, int, short, long, byte, float, double, boolean, char)和对象句柄。

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。 这就是张老师讲的享元模式,节约内存。





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