堆管理 [英] heap management
问题描述
我知道有一个元数据,其中存储辅助信息,当我们仅提供指针时,在free()
和realloc()
期间会用到.
I know there is a meta-data which stores auxiliary information which is used during free()
, realloc()
when we supply only the pointer.
我对堆几乎没有疑问.
- 按进程分配堆栈.毫无疑问,但是不确定堆.无论是全局维护堆信息,还是按进程维护,都会有某种机制来保存有关为该特定进程分配的内存的信息.
- 将如何维护堆信息?我猜哈希机制.我用谷歌搜索,也尝试过.他们中的大多数人都将其解释为特定于实现的方式.
推荐答案
像堆栈一样,堆是按进程的,并且(几乎)是纯用户空间的.
The heap, like the stack, is a per-process, and an (almost) purely user-space thing.
堆管理器使用sbrk
syscall通知操作系统,它打算增加所需的内存量.除了将页面范围从未知"更改为现有,零,从未访问"之外,这几乎没有什么作用(实际上这意味着它们仍然不存在,但是OS假装确实存在).第一次访问页面时,它会出错,并且操作系统会从零缓冲池中拉出零页.
(这可能会稍微复杂一些,因为如果从顶部释放了很多内存,堆管理器也可能会缩小数据段,但基本上就是这么简单.)
The heap manager uses the sbrk
syscall to inform the operating system that it intends to grow the amount of memory needed. This does little apart from change a range of pages from "not known" to "existing, zero, never accessed" (this means in reality that they still don't exist, but the OS pretends they do). When a page is first accessed, it faults, and the OS pulls a zero page from the zero pool.
(It can be slightly more complex, since the the heap manager might also shrink the data segment if a lot of memory has been released from the top, but basically it's as simple as that).
这已经是所有OS都知道的有关堆的信息.其他所有事情,例如拆分块,将释放的块放入列表或类似结构中以及重用块,都发生在堆管理器内部,而堆管理器是程序的直接或间接部分(例如,作为glibc的一部分).
That's already all the OS knows about the heap. Everything else, such as splitting blocks, putting freed blocks onto a list or similar structure, and reusing blocks happens inside the heap manager, which is directly or indirectly (e.g. as part of the glibc) part of your program.
堆管理器到底在做什么取决于实现,至少有六个著名的不同malloc实现以不同的方式工作.例如,参见此或这一个.
What exactly the heap manager is doing is implementation dependent, there exist at least half a dozen well-known different malloc implementations which work in different ways. See for example this one or this one or this one.
堆栈以相同或相似的方式工作.最初保留"一定的内存范围,而不实际保留任何内容(即,不创建页面).提交(创建)了几个页面,最后一页被写保护或不存在,并且以特殊方式记住该页面.当堆栈变大从而触及最后一页时,就会发生故障.如果堆栈仍在其允许的大小内,则从零缓冲池中拉出一个新页面.
The stack works in the same or a similar way. A certain memory range is initially "reserved" without actually reserving anything (that is, without creating pages). A few pages are committed (that is, created) and the last page is either write protected or non-existent and this is remembered in a special way. When the stack grows so this last page is touched, a fault happens. A new page is then pulled from the zero pool, provided that the stack still is within its allowable size.
当进程终止时,对这些页面的所有引用都将被删除,并且(假定它们未与仍保留引用的另一个进程共享)将移交给低优先级后台任务,该任务将其归零并将其添加到零"池".
When the process terminates, all references to those pages are removed and (assuming they are not shared with another process that still holds a reference) handed over to a low priority background task which zeroes them out and adds them to the "zero pool".
这篇关于堆管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!