Loki Library 里包含了一套区别于 GNU Alloctor 的内存分配方式,但是目前并没有稳定版,作者也不再维护。但值得学习。
在之前的文章中已经提到,GNU Alloctor 的缺点在于,内存并不会归还给操作系统。而在 Loki 中,就可以将内存归还给操作系统。
如上图所示,Loki Allocator 内只有3个 class。其中面向用户使用的接口是 SmallObjAllocator
,它的API如下所示
// 第一个参数指定Chunk大小 4096 bytes,第二个参数指定最大可分配的对象大小为256bytes
SmallObjAllocator myAlloc(4096, 256);
<aside> 💡 你也许会注意到,在 loki Allocator 中使用了 vector,不过要注意,这里的 vector 是先使用的标准库的 vector,该 vector 的 Allocator 并非 loki。
</aside>
<aside> 💡 这里为什么要记录上一次 分配 / 回收 的 Chunk,是因为存在一个经验法则,局部性原理,即上一次分配出去的内存,下一次很大可能还是由此分配,上一次回收的内存,下一次还是由此回收。
</aside>
在上面的例子中,指定了 Chunk 大小为 4096 bytes 之后 (实际会因为有 Cookie 存在,会调整为 4080 bytes),ChunkInit 就会根据所需的内存对 Chunk 进行切块。
比如说,目前需要 20 bytes (经过调整之后),那么就会将 Chunk 切割为 204 块。上图在申请了内存空间之后,就会将 Chunk 切割,并借用每一块内存的第一个bytes 记录下序号,从 1 开始。
typedef ::std::vector< Chunk > Chunks;
Chunks chunks_;
// 指向 vector<Chunk> 其中某两个 Chunk
// allocChunk_ 指向 上一次 分配出去过区块的 Chunk
Chunk * allocChunk_;
// deallocChunk_ 指向 上一次 回收过区块的 Chunk
Chunk * deallocChunk_;
// 指向 唯一一个空Chunk 如果没有 则 为 nullptr
Chunk * emptyChunk_;
::Loki::Private::FixedAllocator * pool_;
// 支持分配的最大内存大小
const ::std::size_t maxSmallObjectSize_;
// 用于对齐操作
const std::size_t objectAlignSize_;