4

我知道有一个元数据存储在 期间使用的辅助信息free()realloc()当我们只提供指针时。

我对堆没有什么疑问。

  • 堆栈是按进程分配的。毫无疑问,但不确定堆。堆信息是否是全局维护的,否则每个进程都会有一些机制来保存有关为该特定进程分配的内存的信息。

  • 堆信息将如何维护?我猜散列机制。我也用谷歌搜索并尝试过。他们中的大多数人将其解释为特定于实现的......就像那样。
4

3 回答 3

5

堆,就像堆栈一样,是每个进程的,并且(几乎)纯粹是用户空间的东西。

堆管理器使用sbrk系统调用通知操作系统它打算增加所需的内存量。除了将一系列页面从“未知”更改为“现有、零、从未访问过”(这实际上意味着它们仍然不存在,但操作系统假装它们存在)之外,这几乎没有什么作用。当一个页面第一次被访问时,它会出错,并且操作系统从零池中拉出一个零页。
(它可能稍微复杂一些,因为如果从顶部释放了大量内存,堆管理器也可能会缩小数据段,但基本上就是这么简单)。

这就是操作系统对堆的全部了解。其他所有事情,例如拆分块、将释放的块放入列表或类似结构以及重用块都发生在堆管理器内部,它直接或间接(例如作为 glibc 的一部分)是程序的一部分。

堆管理器正在做什么取决于实现,至少存在六种众所周知的不同 malloc 实现,它们以不同的方式工作。参见例如this one or this one or this one

堆栈以相同或相似的方式工作。某个内存范围最初是“保留”的,但实际上并未保留任何内容(即不创建页面)。一些页面被提交(即创建),最后一页被写保护或不存在,这以一种特殊的方式被记住。当堆栈增长到最后一页被触及时,就会发生错误。然后从零池中拉出一个新页面,前提是堆栈仍在其允许的大小内。

当进程终止时,对这些页面的所有引用都将被删除,并且(假设它们没有与仍然持有引用的另一个进程共享)移交给低优先级后台任务,该任务将它们清零并将它们添加到“零池”中。

于 2012-07-16T10:09:14.507 回答
2

是的,堆也是每个进程的。

有一些堆实现使用每个线程堆来减少锁争用,但这是(用户空间)堆管理器的实现细节。

于 2012-07-16T09:29:37.677 回答
0

阅读这个,它有点旧('07),但有 Damon 概述的相关细节

http://www.blackhat.com/presentations/bh-usa-07/Ferguson/Whitepaper/bh-usa-07-ferguson-WP.pdf

于 2013-02-18T12:07:52.267 回答