什么是内存堆?

What is a Memory Heap?

提问人:H4cKL0rD 提问时间:2/22/2010 更新时间:1/3/2022 访问量:197015

问:

什么是内存堆?

马洛克

评论


答:

8赞 Justicle 2/22/2010 #1

内存堆是用于保存动态分配的内存的常见结构。 请参阅维基百科上的Dynamic_memory_allocation

还有其他结构,如水池、烟囱和桩。

8赞 Ignacio Vazquez-Abrams 2/22/2010 #2

它是进程使用的内存管理器从操作系统分配的内存块。然后,对 et alia 的调用会从该堆中获取内存,而不必直接处理操作系统。malloc()

314赞 LeopardSkinPillBoxHat 2/22/2010 #3

据推测,您的意思是从内存分配的角度来看堆,而不是从数据结构的角度来看(该术语具有多种含义)。

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

  1. 内存是 'dfree
  2. 程序终止

如果对已分配内存的所有引用都丢失了(例如,您不再存储指向它的指针),则会出现所谓的内存泄漏。这是仍然分配内存的地方,但您没有简单的方法来访问它了。泄漏的内存无法回收以用于将来的内存分配,但当程序结束时,操作系统将释放内存。

与此形成鲜明对比的是堆栈内存,堆栈内存是局部变量(在方法中定义的变量)所在的位置。堆栈上分配的内存通常只在函数返回之前存在(有一些例外,例如静态局部变量)。

您可以在本文中找到有关堆的详细信息。

评论

3赞 CodyBugstein 7/3/2015
局部变量如何存在于堆栈中?堆栈一次只允许以非常特定的顺序获取一个变量。如果我需要堆栈中较低位置的局部变量怎么办?
13赞 LeopardSkinPillBoxHat 7/3/2015
@Imray - 在静态类型语言中,局部参数的大小在编译时是已知的。因此,可以通过地址偏移直接从堆栈访问局部变量。无需弹出堆栈即可执行此操作。有关更多详细信息,请参阅此答案
0赞 gaaaaaa 4/28/2022
如果堆只是内存的一部分,那么我不能使用整个 RAM 来存储动态分配的数据?
0赞 webninja 10/18/2022
静态局部变量无法存储在堆栈上。在技术层面上,它本质上是一个变相的全局变量。
27赞 mjv 2/22/2010 #4

内存是内存中的一个位置,可以在随机访问时分配内存。
与以非常定义的顺序分配和释放内存的堆栈不同,在堆上分配的单个数据元素通常以彼此异步的方式释放。当程序显式释放相应的指针时,任何此类数据元素都会被释放,这可能会导致堆碎片化。相反,只有顶部(或底部,取决于堆栈的工作方式)的数据才能被释放,从而导致数据元素以相反的分配顺序被释放。

8赞 Uri 2/22/2010 #5

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

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

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

14赞 fastcodejava 2/22/2010 #6

堆只是一个没有任何顺序分配或释放内存的区域。当使用运算符或类似的东西创建对象时,就会发生这种情况。这与堆栈相反,堆栈以先进后出的方式释放内存。new

-1赞 aya shameimaru 3/2/2021 #7

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

0赞 Suryakant Nikhil 8/27/2021 #8

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

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

堆栈内存中,数据流由自下而上的方法驱动。然后将内存 Arch 命名为 stack。

评论

1赞 Community 8/27/2021
请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。