博客
关于我
loki::allocator
阅读量:161 次
发布时间:2019-02-27

本文共 2250 字,大约阅读时间需要 7 分钟。

文章目录



loki::allocator 是由C++编委会一成员所写,可找到的最新版本是 loki-0.1.7.exe,所以从未发行过。但是并不妨碍学习其中的设计思路和实现方法。其实现颇有暴力美学的味道,但是又能够较好的实现功能,相比于std::alloc,其能够对所管理的内存进行 delete[] 操作(即进行内存回收,交给os,详细见下),同时由于版本迭代很少,也有一定数量的 bug 也会在下面的内容中予以指出。

源码地址见:

同时推荐看下:



1. loki::allocator 结构

loki::allocator 可分为三个嵌套结构,自下而上分别为 Chunk,FixedAllocator,SmallObjAllocator。



2. loki::allocator 使用实例

在这里插入图片描述

在这里插入图片描述
上图中chunk改为block。下图表示的是以p5,p6,p4,p7的顺序对指针所指位置进行 Deallocate() 之后的结果,具体为 myAlloc.Deallocate(p#,64);,所得到的结果图即是下图。
在这里插入图片描述



3. loki::allocator 具体实现


3.1 Chunk 部分实现

loki::allocator中的Chunk的实现细节如下,分为Fixed::allocator::Chunk::Init(),Reset() 和 Release()。其中 Release() 确实是实现了对回收内存的释放。

在这里插入图片描述
Chunk::Allocate()实现如下,即是由firstAvailableBlock的序号和pData的位置来计算要分配的内存地址的位置,同时减少block存量(–blocksAvailableBlock_)。
在这里插入图片描述
Chunk::Deallocate()的实现如下。指针强转之后,将firstAvailableBlock_更改为p的序号,增加block的存量(++blocksAvailableBlock_)。
在这里插入图片描述


3.2 FixedAllocator 部分实现

Allocate()逻辑为:若是当前Chunk仍有block可供分配,则直接分配;若是没有则遍历所有的Chunks,若是找到有可分配内存的Chunk则进行分配,若是没有找到则重新申请一块内存空间,并将其初始化为Chunk,再进行分配。

Deallocate() 则是先调用VicinityFind ( p ) 函数找到需要 deallocate 的位置再调用 DoDeallocate(p)进行内存释放操作。

在这里插入图片描述
VicinityFind()函数主要用于查找 指向所要进行回收的内存 的 指针 所对应的 Chunk是哪个。从FixedAllocator所指的deallocChunk(即上次释放中所指定的chunk)向上和向下进行暴搜,直至找到p所处的chunk为止,再将上次请求释放的空间给释放掉,更新deallocChunk信息。同时有个bug就是,如果p不属于FixedAllocator所管理的内存空间,则会导致死循环。
在这里插入图片描述
FixedAllocator::DoDeallocate()是FixedAllocator进行内存回收的函数。其中调用了Chunk的 Deallocate() 进行内存空间回收 和 Release() 进行内存空间归还给os 的操作。具体的归还细节不表,但是可看出是使用了 Defering 技法的。此外,该版本下的 bug 也在图片中已经写明。
在这里插入图片描述



4. loki::allocator 总结

  • 曾有两个 bug,见 FixedAllocator 部分实现章节,其中的 VinicityFind() 和 DoDeallocate() 的函数实现;
  • 精简强悍,但是手段暴力(for(;;)的使用);
  • 使用array代替list,即数组(vector)代替链表,同时使用索引(index)下标代替指针(pointer);
  • 能够以简单的方式(deallocChunk_->blocksavAilable_ == numBlocks)判定是否进行 chunk 全回收,进而将 memory 归还给操作系统;
  • 有Deferring(暂缓归还)的能力;
  • 和 std::alloc 一样,是一种 allocator,用来分配大量小块不带 cookie 的 memory blocks,由 SBH/malloc 分配的内存带有 cookie,它的最佳客户是容器,但是其本身却 has-a vector。

相比于之前分析的 std::alloc 的内存管理:

  • std::alloc 一旦向 OS 索取了新的 chunk,就不会还给 OS 了,一直在自己的掌控之中。因为它里面的指针拉扯比较复杂,几乎不可能去判断一块 chunk 中给出去的 block 是否全部归还了。但是 loki::allocator 通过利用一个 blocksAvailable_ 变量,就很容易的判断出某一块 chunk 中的 block 是否已经全部归还了,这样就可以归还给 OS。
  • std::alloc 只负责一些特定 block size 的内存管理。如果客户端需要的 block size 它并不支持,那个客户端的 block size 会被取整到最接近的大小 (当然前提是小于它所能够分配的最大的 block size);但是 loki::allocator 能够为不大于最大 block size 的所有 block size 服务。

转载地址:http://qcbb.baihongyu.com/

你可能感兴趣的文章
MySQL-索引的分类(聚簇索引、二级索引、联合索引)
查看>>
Mysql-触发器及创建触发器失败原因
查看>>
MySQL-连接
查看>>
mysql-递归查询(二)
查看>>
MySQL5.1安装
查看>>
mysql5.5和5.6版本间的坑
查看>>
mysql5.5最简安装教程
查看>>
mysql5.6 TIME,DATETIME,TIMESTAMP
查看>>
mysql5.6.21重置数据库的root密码
查看>>
Mysql5.6主从复制-基于binlog
查看>>
MySQL5.6忘记root密码(win平台)
查看>>
MySQL5.6的Linux安装shell脚本之二进制安装(一)
查看>>
MySQL5.6的zip包安装教程
查看>>
mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
查看>>
Webpack 基本环境搭建
查看>>
mysql5.7 安装版 表不能输入汉字解决方案
查看>>
MySQL5.7.18主从复制搭建(一主一从)
查看>>
MySQL5.7.19-win64安装启动
查看>>
mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
查看>>
MySQL5.7.37windows解压版的安装使用
查看>>