什么是内存堆?

248

什么是内存堆(heap)?

8个回答

314

您可能是指从内存分配的角度而非数据结构的角度来看(该术语有多重含义)。

一个非常简单的解释是,是动态分配内存所在的内存区域(即通过malloc函数分配的内存)。从堆中分配的内存将保持分配状态,直到发生以下情况之一:

  1. 内存被free释放
  2. 程序终止

如果对已分配的内存的所有引用都丢失了(例如,您不再存储指向它的指针),则会出现内存泄漏。这意味着内存仍然被分配,但你没有更容易的方法来访问它。泄漏的内存不能用于未来的内存分配,但当程序结束时,操作系统将释放该内存。

相比之下,内存是本地变量所在的位置(即定义在函数内部的变量)。在栈上分配的内存通常只存在于函数返回之前(也有一些例外情况,例如静态局部变量)。

您可以在此文章中了解有关堆的更多信息。


3
局部变量如何存在于栈中?栈一次只允许以非常特定的顺序获取一个变量。如果我需要从堆栈底部某个位置获取局部变量怎么办? - CodyBugstein
13
在静态类型语言中,本地参数的大小在编译时已知。因此,可以通过地址偏移直接从堆栈访问本地变量,无需弹出堆栈。有关详细信息,请参见此答案。 - LeopardSkinPillBoxHat
如果堆只是内存的一部分,那么我不能使用整个RAM来存储动态分配的数据吗? - gaaaaaa
没有办法在堆栈上存储静态局部变量。从技术层面上讲,它本质上是一个伪装成全局变量的变量。 - webninja

27

内存是内存中的一个位置,可以随机访问和分配内存。与不同,堆上分配的单个数据元素通常以异步方式释放,而栈上的内存则按照非常明确定义的顺序分配和释放。当程序显式释放相应指针时,任何这样的数据元素将被释放,并且可能导致堆碎片化。相反,只有位于堆栈顶部(或底部,具体取决于堆栈如何工作)的数据可以被释放,从而导致数据元素按照它们分配的相反顺序被释放。


14

堆是一个可以按照任意顺序进行内存分配或释放的区域。当使用new运算符或类似操作创建对象时会发生这种情况。与此相对,栈则是按照先进后出的原则进行内存释放的。


8

内存堆是保存动态分配内存的常见结构。

参见维基百科上的Dynamic_memory_allocation

还有其他结构,如池、栈和堆。


8

堆是由进程使用的内存管理器从操作系统中分配的一块内存块。调用malloc()等函数时,会从这个堆中获取内存,而不必直接与操作系统打交道。


8
您可能是指堆内存,而不是内存堆。

堆内存实际上是一个大型的内存池(通常是每个进程),从中运行程序可以请求块。这通常被称为动态分配

它与堆栈不同,在堆栈上分配“自动变量”。因此,例如,在C函数中定义指针变量时,将在堆栈上分配足够的空间来容纳内存地址。但是,您经常需要在堆上动态分配空间(使用malloc),然后将该内存块开始的地址提供给指针。


0

内存组织分为两部分:堆内存栈内存

堆内存是主要的工作内存,最低地址是起始地址。

栈内存中,数据流是由下往上驱动的。因此,内存结构被命名为栈。


1
请在您的回答中提供更多细节。目前的写法让人难以理解您的解决方案。 - Community

-1
每个运行的进程都有自己的私有虚拟内存,由操作系统提供。只要可用,操作系统可以在任何时候将其映射到物理内存,否则将根据需要映射到磁盘和交换空间。这个虚拟内存被逻辑地分成不同的段,以组织不同类型的数据。代码段保存可执行指令。数据段保存静态数据,如全局或静态变量。堆栈保存由调用和返回函数自动管理的本地数据。所有这些段都是固定大小的,即使堆栈也是如此,只是使用的部分可以增长或缩小,并在函数返回时被回收。唯一没有在应用程序启动时预分配和固定大小的段是堆。应用程序可以在运行时向操作系统请求新的内存分配,操作系统将保留您应用程序的虚拟空间的一部分,并根据需要将其提交给物理内存。操作系统将返回一个指向新分配的堆内存的指针,该指针保存新块的基址或起始地址。该指针位于堆栈上,当该堆栈空间被回收时,您的指针将不再在作用域内,因此您无法访问该内存块。如果您不告诉操作系统您已经完成了它,以便它可以回收它,那么就会有没有访问手段的僵尸内存存在,如果您的应用程序在从未归还内存的情况下继续请求内存,当系统内存不足时,它将崩溃。因此,释放或至少将指针传递给定义它的作用域外部的另一个指针是非常重要的,这样您就可以维护与堆空间中分配的内存的接口。我建议进一步研究虚拟内存并了解各个段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接