堆栈:堆栈被用作临时暂存区,供当前正在执行的代码块以及任何称为当前块的块和任何称为该块的块等等使用。当前块存在时,它所使用的局部变量被遗忘。正如名称所示,堆栈以后进先出的方式使用。
该堆栈最重要的用途之一是跟踪当前的调用链。当一个函数调用另一个函数时,调用者将下一条指令的地址(返回地址)推入堆栈。当每个函数退出时,它会将其调用者的返回地址从堆栈中弹出,并继续执行从该地址开始的代码。它也用于在调用者和被调用者之间传递函数参数和返回值。
堆:堆是不同的 - 有没有特定的顺序。如果你想在一段代码中分配内存,并让该内存超出块的末尾,你可以将它分配到堆上。当然,您还需要在某处存储指针/引用,以便其他代码可以找到该内存;大多数语言提供住宿。
速度:速度的差异并不是由于内存本身的任何属性 - 正如你在你的问题中所说的那样,栈和堆通常都在相同的物理内存中。在堆栈中分配空间很快,原因在于堆栈的LIFO性质:如果将某些东西压入堆栈,只能有一个地方结束。相比之下,在堆上分配块需要在内存中找到足够大的连续空闲区域。堆栈分配可以像单条指令一样快;堆分配需要调用内存分配功能,如malloc()
。
静态与动态:在堆上分配内存是动态的 - 是否分配块和块的大小可以根据程序在运行时接收的输入来确定。在堆上分配的内存区域甚至可以根据需要调整大小。它也可能是也可以动态分配堆栈中的内存(请参阅C标准库函数alloca()
),但是当前函数退出后该内存将立即丢失。堆栈分配通常是静态的 - 编译器确定(非注册)参数,返回数据和本地变量需要多少空间,并且在调用该函数时生成代码以在堆栈中保留必要的空间。
示例:想象一下,您正在创建一个文字处理器。您无法提前知道文档的大小,甚至可能同时使用多少个文档。与此同时,只要用户想让它们保持打开状态,就希望用户的文档保留在内存中。如果您尝试为堆栈中的文档分配内存,您会发现很难一次打开多个文档,并且您需要创建一个创建,编辑,保存和关闭文档的函数。在堆上分配空间允许您创建尽可能多的文档,每个文档都根据其包含的数据进行适当的大小设置,并避免将文档的生命周期与任何特定功能的生命周期挂钩。
总结:简而言之,堆栈保存变量的值(有时使用寄存器),而堆用于分配将在当前块的生命周期之外使用的内存。
http://stackoverflow.com/questions/7123936/why-is-there-a-stack-and-a-heap – drdwilcox
http://stackoverflow.com/questions/79923/what-and-where-are堆栈和堆 –