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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王思兰 黑马帝   /  2011-7-21 00:05  /  3598 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

堆内存和栈内存,看了张老师的视频后很模糊,不知道具体什么意思,上百度搜了几个,但也没完全弄明白,希望有人能说一个通俗易懂的说法,能清楚区分堆内存和栈内存?

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 楼下会告诉你的。

查看全部评分

8 个回复

倒序浏览
黑马网友  发表于 2011-7-21 00:14:10
沙发
内存分为5个部分:栈,堆,方法区,本地方法区,寄存器
栈:存放局部变量,每一个变量要使用都要手动初始化,变量一用完就释放内存。
堆:存放的是引用数据类型(数组,对象等),凡是用new建立的实体都存放在堆中,这个实体的首地址被存放在栈中,而栈中这个存放首地址的变量就是引用型变量(一个实体可以同时有多个引用型变量指向它)。
堆内存中一些实体,没有引用变量指向它们(即不再被使用),那么这些实体就是垃圾,占用了内存空间,java中靠垃圾回收机制来删除这些实体(不定时回收),释放出内存空间。堆内存中的所有变量都有默认初始化值。

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 内存分为5个部分

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-7-21 00:45:05
藤椅
内存分为两个部分:栈内存和堆内存,它们内部的机制不一样,内存本身就是装数据的,通俗的打个比方,我们可以把内存想象成一个一个的箱子,在栈内存中:每个箱子只装一个数据,数据和数据之间没联系,在堆内存中:每个箱子也只装一个数据,但数据和数据之间可以存在联系,即几个箱子可以装进一个大箱子,看成一个整体,且我们只需要记住第一个箱子的编号,第二个箱子及依次向下箱子的编号只需用第一个箱子的编号加上1,2,3....即可,然后把第一个编号存进栈内存的一个箱子中,当我们要用到这个大箱子里的数据时,我们就可以从栈内存存放编号的那个箱子取出编号,按编号去堆内存中取数据

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 内存分为两个部分,你和楼上在讨论一下。

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-7-21 03:16:44
板凳
[quote] 原帖由 [i]张晴[/i] 于 2011-07-21 00:45 发表 [url=http://bbs.itheima.com/redirect.jsp?goto=findpost&pid=4268&ptid=360][img]http://bbs.itheima.com/images/common/back.gif[/img][/url]内存分为两个部分:栈内存和堆内存,它们内部的机制不一样,内存本身就是装数据的,通俗的打个比方,我们可以把内存想象成一个一个的箱子,在栈内存中:每个箱子只装一个数据,数据和数据之间没联系,在堆内存中:每个箱子也只装一个数据,但数据和数据之间可以存在联系,即几个箱子可以装进一个大箱子,看成一个整体,且我们只需要记住第一个箱子的编号,第二个箱子及依次向下箱子的编号只需用第一个箱子的编号加上1,2,3....即可,然后把第一个编号存进栈内存的一个箱子中,当我们要用到这个大箱子里的数据时,我们就可以从栈内存存放编号的那个箱子取出编号,按编号去堆内存中取数据 [/quote]
回复 使用道具 举报
黑马网友  发表于 2011-7-21 13:49:35
报纸

栈内存和堆内存(经典引用)

原来也不太懂的,但现在懂了,因为我查找并学习了这方面的资料(网络好强大!),现与大家分享,为大家解惑。因这内容较多,这里贴出网址,以便大家查看。

1.栈内存和堆内存
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存

在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为改变量分配的内存空间,该内存空间可以立刻被另作他用。

堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因。但是在写程序的时候,可以人为的控制。
[img]http://blogimg.chinaunix.net/blog/upfile2/080423142951.jpg[/img]
还有部分内容,请查看此文章:[url]http://blogold.chinaunix.net/u2/67175/showart_573932.html[/url]
2.Java内存分析
在JAVA中,有六个不同的地方可以存储数据:
1. 寄存器(register)。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。
2. 堆栈(stack)。位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。
3. 堆(heap)。一种通用性的内存池(也存在于RAM中),用于存放所以的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代码。用堆进行存储分配比用堆栈进行存储存储需要更多的时间。
......
还有部分内容,请看文章:[url]http://java999.blog.51cto.com/259217/134359[/url]

3.JAVA内存管理
为方便管理,Java虚拟机对应的在内存中划分了三个区域“方法区”、“堆区”和“栈区”,分别保存类结构、对象中的数据和变量(基本型和引用型)。 这三个内存区域都有大小限制,任何一个区域内存溢出都会导致程序出现错误,栈内存溢出会发生StackOverflowException错误,堆内存溢出会发生OutOfMemoryError错误。
......
还有部分内容,请查看文章:[url]http://www.xaygc.com/javase_05_1.html[/url]

评分

参与人数 1技术分 +3 收起 理由
admin + 3 太专业了!!

查看全部评分

回复 使用道具 举报
看了四楼推荐的网站,里面举得例子容易懂,文字太多会让我看不下去:#  ,举个例子就很容易懂了,谢谢楼上各位的解释说明,我的理解就是
class a
{
    public static void main(String args[])
     {
            myarray=new array[];
             int a =1;
     }
}  
那么myarray和a是在堆内存中的,new array[]和1是在栈内存中的,
内存只有两部分吧,字符串常量池是单独的吗,不存在与内存中?

评分

参与人数 1技术分 +1 收起 理由
admin + 1 不要怕麻烦哟

查看全部评分

回复 使用道具 举报
袁春龙 黑马帝 2011-7-21 23:14:03
7#

回复 地板 的帖子

《myarray=new array[]; 》对吗?

简单点的
eg:int[] x=new int[20];因为由new关键字产生,所以就会开辟出堆内存,将那20个数组元素存进去,然后把这些元素的首地址就放在栈内存中。栈内存中存放着堆内存的首地址,所以它们貌似被一根线牵着,当x的值被改变或者为null之后,这段堆内存便会失去领导,之后被垃圾回收器消灭掉。
[ 本帖最后由 袁春龙 于 2011-07-21  23:22 编辑 ]
回复 使用道具 举报
黑马网友  发表于 2011-7-21 23:38:54
8#

回复 7 # 的帖子

:funk:
那改成这个   int array[];
                          array=new int[3];
回复 使用道具 举报
黑马网友  发表于 2011-7-21 23:54:24
9#
根据张老师视频里说的和7#说明的定义一个数组int []x;因为没有产生对象,所以就没堆内存,栈内存因为没有堆内存首地址就显示的是问号
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马