代码改变世界

.net 垃圾回收学习[Stack 和 Heap的理解][续1]

2011-08-20 15:26  一一九九  阅读(290)  评论(0编辑  收藏  举报

from: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

这里继续看其他人答案和补充,深入理解。

答案二

   Stack:

  • 和heap一样存储在计算机RAM中。
  • 在stack上创建的变量一旦超过了生命周期会被自动回收释放。
  • 和heap相比,为变量分配空间更快一些。
  • 实现为实际的Stack的数据结构。
  • 存储局部数据,返回地址,用于参数传递
  • 当stack使用太多的时候会栈溢出。
  • 在stack上创建的数据可以不通过指针来访问。
  • 如果你在编译之前就知道有多少空间需要分配,并且需要分配的空间不是很大的话,你会使用Stack。
  • 当程序启动的时候通常已经设定了一个最大值。

Heap:

  • 和stack一样存储在计算机RAM中。
  • 在heap上的变量必须手动的被释放掉,并且永远都不存在超出范围(生命周期,比如函数调用)的情况。一般通过Delete, Delete[],  free来释放。
  • 和stack上的变量分配相比要慢一些。
  • 根据program对内存空间的需要申请和分配。
  • 当分配和释放多次后,存在内存片段的问题。
  • 在C++中,在heap上创建的数据被指向某个Poniter,一般通过allocate和New进行分配。
  • 加入申请的内存区块比较大的话,可能存在分配失败的情况。
  • 当你不知道你在运行时确切的知道需要多少内存或者需要内存空间比较大的情况下,一般会采用heap的结构。
  • 一般是memory leak的源头。

示例:

int foo()
{
 
  char *pBuffer; //<--nothing allocated yet
  bool b = true;
  if(b)
  {
    //Create 500 bytes on the stack
    char buffer[500];
 
    //Create 500 bytes on the heap
    pBuffer = new char[500];
 
   }//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;

       The pointer pBuffer and the value of b are located on the stack, and are mostly likely allocated at the entrance to the function. Depending on the compiler, buffer may be allocated at the function entrance, as well

答案三

           关于stack和heap的最重要的区别是谁的内存能够被分配。他们可以被以不同的方式来实现,但是在基本的概念上是一致的。

  • 对于stack来说,放置在stack上的items是以他们被放置的顺序存放的,而且只能移除最顶端的哪一个。只要别溢出。如下图:
  • iStock_stackPapersSml
  • 对于heap来说,是不需要关心放置到heap上的item的顺序的,你可以移除或者获取任何一个而不仅仅是顶端的那个。如下图:
  • thm_licorice-allsorts

  • 在多大的程度上他们是被OS或者Language Runtime来操纵的呢?
             如上所述,heap和stack是通用的概念,可以用很多方式来实现。Programs通常拥有一个Stack叫做Call stack,CallStack用来存储当前函数相关的信息,比如说采用一个指针保存函数被谁调用的开始点,任何静态分配的局部变量。因为函数经常调用其他函数并且返回,所以Stack动态的增大或者缩小来保留函数调用过程中的信息。Program通常不能控制调用stack,一般是由Programming language , OS 或者系统架构决定的。
           heap是指可以被动态和任意分配的内存,而不需要在乎分配的顺序。内存通常由系统来分配,由applcation调用相关的API来完成相关工作。管理动态分配的内存需要很大的开销,这通常由OS来完成(there is a fair bit of overhead required in managing dynamically allocated memory, which is usually handled by the OS).
  • what is their scope?
          callback是一个十分底层的概念,和programming 中的Scope没有太大的关系。假如你反编译一些代码你会发现一些指针风格的引用指向stack,就我们关注的高级语言来说,语言会强加他自己的Scope的概念。关于Stack的一个关键点就是当一个函数返回的时候,任何和那个函数相关的局部变量都会被从Stack中释放。在heap上,则很难说哪种情况,Scope是被OS所公开的(注:应该指是由OS分配的),但是Programming language 可能会强加自己的规则。 处理器架构和OS使用Virtual Address, 处理器和os 负责将这些Virtual address翻译成为相对应的物理地址,记录和追踪者哪些pages属于哪些Application。 你不需要担心这些,你只需要使用你的progrmming language 提供的方法分配和释放memory, 检查错误即可。
  • what datemines the size of each of them?   
         这个是由language, 编译器,操作系统和机构据定的。Stack通常是提前分配的,因为根据定义它是一个连续的内存块,编译器和OS决定了他的大小,你不会在Stack上存储大块的数据,所以他会足够大到应该永不会被用完的程度,除了无终止的栈溢出或者其他不正常的程序命令。 heap代表任何可以被动态分配的内容,根据你观察他的角度来说,他通常是一个变化的大小。在现在的处理器和操作系统中,它工作的方式各种各样,所以你不需要深入理解他是如何工作的,除了你不能使用你还没有分配的内存或者使用已经分配了的内存。
  • what makes one faster?
         Stack更快一些因为他是连续的内存块,不需要单独维护没有分配的内存块,只需要一个指针指向栈的顶部即可。通常在栈上的后续操作所需要的内存都是附近的内存,而这些可以被处理器来进行优化。