我知道有一个元数据存储在期间使用的辅助信息free()
, realloc()
当我们只提供指针时。
我对堆几乎没有疑问。
- 堆栈是按进程分配的。毫无疑问,但对堆不确定。无论堆信息是全局维护的,还是每个进程都会有某种机制来保存有关为该特定进程分配的内存的信息。
- 堆信息将如何维护?我猜是散列机制。我也用谷歌搜索并尝试过。他们中的大多数人将其解释为特定于实现的..就像那样。
堆和堆栈一样,是每个进程的,并且(几乎)纯粹是用户空间的东西。
堆管理器使用sbrk
系统调用通知操作系统它打算增加所需的内存量。除了将一系列页面从“未知”更改为“现有、零、从未访问过”(这意味着实际上它们仍然不存在,但操作系统假装它们存在)之外,这几乎没有什么作用。当第一次访问页面时,它会出错,操作系统会从零池中提取零页面。
(它可能稍微复杂一些,因为如果从顶部释放了大量内存,堆管理器也可能会缩小数据段,但基本上就这么简单)。
这已经是操作系统所知道的有关堆的所有信息。其他一切,例如分割块、将释放的块放入列表或类似结构以及重用块都发生在堆管理器内部,堆管理器直接或间接(例如作为 glibc 的一部分)是程序的一部分。
堆管理器到底在做什么取决于实现,至少存在六种众所周知的不同 malloc 实现,它们以不同的方式工作。参见示例this one http://g.oswego.edu/dl/html/malloc.html or this one http://goog-perftools.sourceforge.net/doc/tcmalloc.html or this one http://www.hoard.org/.
堆栈以相同或相似的方式工作。某个内存范围最初是“保留”的,但实际上没有保留任何内容(即不创建页面)。一些页面被提交(即创建),最后一个页面要么被写保护,要么不存在,并且以特殊方式记住这一点。当堆栈增长以致最后一页被触及时,就会发生错误。然后从零池中提取一个新页面,前提是堆栈仍在其允许的大小范围内。
当进程终止时,对这些页面的所有引用都将被删除,并(假设它们不与仍保留引用的另一个进程共享)移交给低优先级后台任务,该任务将它们清零并将它们添加到“零池”。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)