堆内存和平板分配

我对堆和自由列表感到困惑.我有几个问题,我对C ++如何在C中工作有我自己的理解.如果我错了,请纠正我.

>堆内存是否组织为数据的链接列表(空闲列表)
块?
>堆内存和空闲列表之间有区别吗?

我对存储分配的理解(有待改进): –
当我们调用malloc时,它会在堆中分配内存,并通过从空闲列表中选择合适大小的数据块来实现,对吗?

当malloc返回某个特定的内存块时,它将从空闲列表中删除,并在页表中更新该内存块的物理地址.

当使用free()释放内存时,数据块将插回到空闲列表中,并可能减少碎片,与相邻块结合,并清除页表条目中的当前位.

因此整个堆是一个自由列表(空闲块的链表)分配的数据块.

这是存储分配的全面情况吗?

编辑:来自Linux内核开发(Robert Love)关于内存管理,平板分配的章节

“A free list contains a block of available, already allocated, data
structures. When code requires a new instance of a data structure, it
can grab one of the structures off the free list rather than allocate
the sufficient amount of memory and set it up for the data structure.
Later, when the data structure is no longer needed, it is returned to
the free list instead of deallocated. In this sense, the free list
acts as an object cache, caching a frequently used type of object.”

自由列表被称为“可用,分配的数据结构块”.

>当它在免费列表中时如何分配?
>如何将一块内存返回到空闲列表_not_与解除分配该块一样?
> slab分配与存储分配有何不同

malloc()与页表实际上没有关系;它分配虚拟地址,内核负责跟踪页面实际存储在物理RAM或磁盘上的位置.

malloc()通过brk()系统调用与内核交互,它要求内核为进程分配更多页面,或者将页面释放回内核.所以实际上有两个级别的内存分配:

>内核将页面分配给进程,使这些页面不可供其他进程使用.从内核的角度来看,页面可以位于任何位置,页面表可以跟踪它们的位置,但从进程的角度来看,它是一个连续的虚拟地址空间. brk()操作的“程序中断”是内核允许您访问的地址之间的边界(因为它们对应于已分配的页面)和如果您尝试访问它们将导致分段错误的地址.
> malloc()分配程序数据段的可变大小部分供程序使用.当数据段的当前大小内没有足够的可用空间时,它使用brk()从内核获取更多页面,从而使数据段更大.当它发现数据段末尾的某些空间未被使用时,它使用brk()将未使用的页面返回给内核,从而使数据段更小.

请注意,即使在该进程中运行的程序实际上没有使用任何页面,也可以将页面分配给进程(由内核).如果你释放()一块位于数据段中间的内存块,free()的实现就不能使用brk()来收缩数据段,因为在更高的地址上还有其他分配的块.因此,从内核的角度来看,页面仍然分配给您的程序,即使它们是从malloc()的角度来看是“自由空间”.

你对自由列表如何工作的描述听起来对我来说是正确的,尽管我不是如何实现内存分配器的专家.但是您从Robert Love发布的引用听起来像是在讨论Linux内核中的内存分配,这与用户空间进程中malloc()的内存分配无关.这种免费列表可能有不同的作用.

相关文章
相关标签/搜索