Heap And Stack 堆与栈的区别

交代一下背景,最近一直在看C++的相关知识,今天刚好看到“引用”这一部分。于是好奇心驱使,我想知道它与java的引用到底有什么不同,于是开始搜索大法,java的引用更加与c++的指针更加类似,但是也不一样,当然这不是重点。然后搜索的时候,突然又想知道在内存中的存储情况,于是开始搜索……,搜索……。对于heap与stack的区别我又模糊了,于是到了今天的重点,顺便记录一下自己搜索的成果。

英文好的同学可以直接看
https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/https://www.youtube.com/watch?v=450maTzSIvA
特别是上面的这个视频解释的特别生动形象,建议大家都看一下。
我这里主要也是引用别人的文章,还请各位勿怪。

堆和栈在什么位置?

答:他们都存在计算机的RAM中,如果想进一步知道虚拟内存的可以移步这里 How Virtual Memory Works,还有这个视频(推荐,讲解的很清楚)https://www.youtube.com/watch?v=qlH4-oHnBb8

在线程中是如何与堆、栈进行交互?在多线程中,堆与栈又是怎么样一个机制?

答:在一个多线程并发的应用中,每个线程都有自己的栈。但是所有不同的线程共享一个堆,由于不同的线程共享一个堆,必然导致不同的线程之间存在协调关系,不同的线程在同一时间不会访问相同的内存地址。

对象可以保存在栈上吗?

答:可以,一个对象可以被保存在栈中,如果你在一个方法函数中没有通过new关键字创建一个对象,那么这个对象就会被存在栈中。示例代码(c++)如下:

void somefunction( )
{
/* create an object "m" of class Member
    this will be put on the stack since the 
    "new" keyword is not used, and we are 
   creating the object inside a function
*/

  Member m;

} //the object "m" is destroyed once the function ends

一旦方法执行完毕,对象“m”就会从栈中移除。
再看一段代码


void somefunction( )
{
/* create an object "m" of class Member
    this will be put on the heap since the 
    "new" keyword is used, and we are 
   creating the object inside a function
*/

  Member* m = new Member( ) ;

  /* the object "m" must be deleted
      otherwise a memory leak occurs
  */

  delete m; 
} 

以上对象是通过new 关键字创建的,因此这个对象存在内存堆中。在c++中需要我们手动移除,否则会造成内存泄漏

栈的大小可以增大吗?堆的内存大小可以增大吗?

答:栈的内存大小是一个固定值,不能增加(部分语言可以)。因此,如果栈的内存没有足够空间的时候,就会出现stack overflow,经常出现在很多嵌套方法使用的时候,或者是存在一个死循环。
而堆的内存可以通过系统机制调大,这是一点很重要的区别

堆与栈哪个速度更快?

栈的读写速度更快,因为分配内存的机制,只是移动指针,而堆还要做查找等操作。

下面附上一张图说明堆和栈的关系,图片来源于https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
这里写图片描述

还有更加形象的图,用于说明为啥栈比堆要快:同样来源于上面的网址

这里写图片描述

这里写图片描述

一团乱糟糟的heap与整齐的stack,自然没法比。

关于java的示例
这里写图片描述

其他常见问题(持续更新)

  • 全局变量也是放在栈里吗?
    答案:否,放在堆里
  • 静态变量、常量存放在哪里?
    答案:还有一个内存区域叫做方法区
阅读更多
换一批

没有更多推荐了,返回首页