为什么要设堆区和栈区?

baidong008 2014-07-22 10:28:58
今天去一公司面试,问了这么个问题:为什么要设堆区和栈区?
我说栈区是存放程序的局部变量、基本数据类型变量和引用类型变量的引用,在变量生命周期结束后系统会自动释放这部分内存。
但是堆区是存放对象引用的实体,系统不会自动释放这些空间,要么程序员手动释放,要么像java这样的垃圾回收机制。

但是貌似面试官还是不满意这个回答,他说我们也可以把局部变量放到堆区啊,我们自动释放不就行了......

求大牛指点?这两者的本质区别,或者说当初要设这俩区的初衷是什么?
...全文
2882 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
vnvlyp 2014-07-23
  • 打赏
  • 举报
回复 10
不知道面试出这种题目是出于什么目的?纯粹让你答不好? 要问Java为什么要堆栈,那就要问C为什么要堆栈,问C为什么要堆栈就要问以前写汇编的为什么写着写着就喜欢把内存分两块来用,至于这个问题你跑去C板块和汇编板块估计都没几个人能让你信服地说清楚原因,我不是专门写C和汇编的,但至少用8051汇编写了很多程序,用x86汇编练了手,所以只简单说说我的看法。 首先汇编里,变量的概念几乎没有了,有的只是各种内存地址,不管是实地址还是虚地址,你访问一个变量就是靠地址,所以如果你不记住一个变量的地址,你就没办法去操作它,这就产生了问题,如果你的程序要1000个变量,你就把他们的地址全记下来吗?这显然是不现实的,首先这会浪费很多空间,因为几乎任何操作都离不开操作变量,也就是地址,那么就相当于你要用两倍甚至更多的空间来表示你的程序,而一半浪费在地址上,其次这样写程序也是没有效率的,1000个变量,难道你能把他们的地址全背下来吗?或者说当你看到地址0x1234的值赋值给地址0x2345时,你如何记得起0x1234和0x2345是两个干什么用的变量? 所以以一种系统的方法管理内存就显得尤为重要,毕竟我们要用计算机来方便自己,而不是拿来自虐。经过很多人的摸索,人们发现变量主要是两种形式,一种内容短小(比如一个int整数),需要频繁访问,但是生命周期很短,通常只在一个方法内存活,而另一种内容可能很多(比如很长一个字符串),可能不需要太频繁的访问,但生命周期较长,通常很多个方法中可能都要用到,那么自然将这两类变量分开就显得比较理性,一类存储在栈区,通常是局部变量、操作符栈、函数参数传递和返回值,另一类存储在堆区,通常是较大的结构体(或者OOP中的对象)、需要反复访问的全局变量。 堆区就是各种慢,申请内存慢,访问慢,修改慢,释放慢,整理慢(或者说GC垃圾回收),但优点也不言而喻,访问随机灵活,空间超大,在不超可用内存的情况下你要多大就给多大。 栈区就像临时工,干完就跑,所以超快,但是缺点也很多,比如生命周期短,一般只能在一个方法内存活,又比如你需要事先知道需要多大的栈(事实上绝大多数语言栈区要分配的大小编译期就确定了,Java就是这样),而且通常最大栈区可用内存都很小,你不可能往栈区里堆很多数据。 总之还是觉得面试Java程序员死扣这个问题,只能说明他们自己有问题,如何当做一个讨论来考考面试者知识面是否广阔还行,真当技术问题来像模像样地考是不是脑子烧了?
Yoara 2014-07-22
  • 打赏
  • 举报
回复
引用 6 楼 Yoara 的回复:
栈区是线程独享的。 堆区是线程共享的。 这里面还涉及到了java内存模型。线程内部的操作在栈上操作,如果没有同步策略,数据不会立刻同步到主存。 你可以把栈想像成高速缓存。
特别的,虚拟机的C2级别的优化包含一种叫做“栈上分配”的策略,如果用逃逸分析确定某对象不会逃逸,原本堆上分配的策略是可以转为栈上分配的(如果对象内存开销不是太大)。 栈区的好处还包括是每次方法调用的入栈和出栈,都意味着栈桢的创建和销亡,省去了资源回收的操作。
Yoara 2014-07-22
  • 打赏
  • 举报
回复
栈区是线程独享的。 堆区是线程共享的。 这里面还涉及到了java内存模型。线程内部的操作在栈上操作,如果没有同步策略,数据不会立刻同步到主存。 你可以把栈想像成高速缓存。
zhjdg 2014-07-22
  • 打赏
  • 举报
回复
乱说: ISBN 跟 图书的关系。 索引 跟 实体的关系。
还有多远 2014-07-22
  • 打赏
  • 举报
回复
栈供以存储函数调用时传递的参数和函数返回的地址,堆用以动态申请内存?
loong0306 2014-07-22
  • 打赏
  • 举报
回复
我感觉就应该是 先进后出额。。
baidong008 2014-07-22
  • 打赏
  • 举报
回复
引用 1 楼 dandan8989251 的回复:
你忘记先进后入的模式了
栈区跟数据结构里的栈,感觉也不是一回事啊
dandan8989251 2014-07-22
  • 打赏
  • 举报
回复
你忘记先进后入的模式了

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧