分配与管理机制
到目前为止,我们对内存的概念有了初步的了解,也掌握了一些基本的语法。接下来我们要讨论如何进行有效的内存管理。
设计高效的内存分配据*通常会考虑到以下几点:
①尿可能减少内存碎片,提高内存利用率
②尽可能提高内存能访问局部性
①设计在不同场合上话配网
④考虑存对齐
含freelist的分配器
我们首先来考虑一种能够处理任何请求的通用分配器。
一个非常朴素的想法是,对于释放的内存,通过■闲内存*链楼加来,称为freclist。
称合分配内存时,无定要求的内存块,如果不存在,再从未分配内存中获取;当我们找到合适的内存块后,分配合违的内存,并将多余的部分放回reelist,
释放内存时,将内存插入到空闲链表,可能的话,合并前后内存快。
其中,一些细节问题值得考虑:
①空网空间应该如何进行管理?
我们知道freelistst是用于管理空体内存的,但是freelist木身的存储也需要占用内存。我们可以按如下两种方式存储frefreelis::
·息式空链表
将空闲链表信息与内存块存储*在一起,主要记录大小,已分配位等信息。
·显式空流链表
单独维护一块空间来记录所有空闲块信息。
·分离适配(segregated-treelist)
将不同大小的内存块放在一起容易造成外部碎片,可以设置多个freelist,并让每个freelist存储不同大小的内存块,申请内存时选择满足条件的最小内存块。
位图
除了freelist之外,还可以考虑用0.1表示对应内存区域是否已分配,称为位图。
②分配内存优先分配耶决内存?
一般而高,从策略不同来分,有以下几种常见的分配方式:
·首次适应(first-ft)找到的第一个满足大小要求的空习区
·最体活
的最小空
闲区
·循环首次造应(next-fi):在先前停止搜索的到的第一个港层大小要求的空地方用区
科放内存后如何放置到空流链表中?
·直接放回证表头部/尾部
·按照地址顺序放回
这几种策昭本质上都是取金问题:分配/放回时间复杂度*如果低,内存碎片就有可能更多,反之亦然。
buddy分配器
按照一分为二,二分为四的原则,直到分裂出一个满足大小的内存块:合并的时候看buddy足否空闲,如果足就合并。
多可以通过位运算*直接算出buddy,budbudcy,速度较快。但内存碎片较多。
含对齐的分配器
一般而离,对于通用分配器来说,都应当传同对齐的内存块,即根据对齐运,分配比请求多的对齐的内存。
如下,是ue4中计单对齐的方式,它返回和对齐量向上对齐后的伯,其中Algnment应为2的幂次。
复用代码
tempe
FORCEINLINE constexpr T Al gn(T Va.uint64 Aigrmentl
}
statissert(Tlslrtegral:Value llTlsPointer=Value.'Align expects ancas er seintenter type):-
rcturn(TXliuint64)Val+Alignment-1)& -(Alignment-1));1
其中~(Alignmert-1)代表的是高位淹码,类似于11110000的格式,它将到除低位。在对Val进行掩码计算时,加上Alignment-1的做(+al%a,避免Val值过小得到0的结果。
请登录后发表评论
注册
停留在世界边缘,与之惜别