我很困惑heap
and free list
。我有几个问题,我对C中malloc的工作原理有自己的理解。如果我错了,请纠正我。
- 堆内存是否被组织为数据的链表(空闲列表)
块?
- 堆内存和空闲列表有区别吗?
我对存储分配的理解(有待改进):-
当我们调用malloc时,它会在堆中分配内存,并通过从堆中选择一个合适大小的数据块来分配内存。free list
, 正确的 ?
当 malloc 返回某个内存块时,它将从空闲列表中删除,并在页表中更新该内存块的物理地址。
当内存被释放时使用free()
,数据块被插回到空闲列表中,并且可能,为了减少碎片,与相邻块结合,并且present
页表项中的位被清除。
所以整个堆是一个空闲列表(空闲块的链表)+分配的数据块。
这是存储分配的全面描述吗?
编辑:来自Linux内核开发(Robert Love)关于内存管理的章节,板坯分配
“空闲列表包含可用的、已分配的数据块
结构。当代码需要数据结构的新实例时,它
可以从空闲列表中获取结构之一而不是分配
足够的内存量并为数据结构设置它。
稍后,当不再需要该数据结构时,将其返回到
空闲列表而不是释放。从这个意义上说,空闲列表
充当对象缓存,缓存常用类型的对象。”
空闲列表被称为“可用的、已分配的数据结构块”。
- 如何已分配,当它在空闲列表中时?
- 以及如何将一块内存返回到空闲列表_not_ 与取消分配该块相同吗?
- slab 分配与存储分配有何不同
malloc()
与页表并没有真正的关系;它分配虚拟地址,内核负责跟踪页面实际存储在物理 RAM 或磁盘上的位置。
malloc()
通过与内核交互brk()
系统调用,要求内核为进程分配更多页面,或将页面释放回内核。所以内存分配实际上有两个级别:
- 内核将页面分配给进程,使这些页面无法被其他进程使用。从内核的角度来看,页面可以位于任何地方,并且它们的位置由页表跟踪,但从进程的角度来看,它是一个连续的虚拟地址空间。 “程序中断”
brk()
操作是内核允许您访问的地址(因为它们对应于分配的页面)和如果您尝试访问它们将导致分段错误的地址之间的边界。
-
malloc()
分配程序数据段的可变大小部分以供程序使用。当当前数据段大小内没有足够的可用空间时,它会使用brk()
从内核获取更多页面,使数据段更大。当它发现数据段末尾的某些空间未被使用时,它使用brk()
将未使用的页面返回给内核,从而使数据段变小。
请注意,即使在该进程中运行的程序实际上并未将页面用于任何用途,也可以将页面分配给进程(由内核)。如果你free()
位于数据段中间的一块内存,free()
不能使用brk()
缩小数据段,因为在更高的地址上仍然有其他分配的块。因此,从内核的角度来看,这些页面仍然分配给您的程序,即使它们从内核角度来看是“可用空间”。malloc()
立场。
您对空闲列表如何工作的描述对我来说听起来很正确,尽管我不是内存分配器如何实现的专家。但是您从 Robert Love 发布的引用听起来像是在谈论 Linux 内核中的内存分配,这与 的内存分配无关malloc()
在用户空间进程内。这种空闲列表的工作方式可能有所不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)