程序员效率工具:Walloc

更多互联网新鲜资讯、工作奇淫技巧关注原创【飞鱼在浪屿】(日更新)
【程序员效率工具:Walloc】内存分配器的名称为“ walloc” , 其中w意思是WebAssembly(可用于js调用) 。
Walloc的设计具有以下优先顺序:

  1. 独立的 。 不需要stdlib;可以包含在项目中 , 而无需引入其他任何内容 。
  2. 合理的分配速度和碎片/开销 。
  3. 体积小巧 , 最大程度地减少了下载时间 。
  4. 标准接口:替代malloc 。
  5. 单线程 。
walloc项目的GitHub地址:
首先 , 要构建walloc , 编译命令:
clang -DNDEBUG -Oz --target = wasm32 -nostdlib -c -o walloc.o walloc.c实现细节线性存储器具有通常的数据段 , 堆栈段和堆段 。 数据和堆栈放在最前面 。 堆从&__ heap_base符号开始(此符号由链接器计算和定义) 。 wasm程序可以根据需要使用&__ heap_base以上的所有字节 。 因此 , &__ heap_base是walloc管理的内存地址下限 。
程序员效率工具:Walloc文章插图
不同的工具链使用了几种不同的数据和堆栈顺序 。 下面图表很好地总结了这一点:
程序员效率工具:Walloc文章插图
防止意外溢出(实际上是下溢)的明智做法是使堆栈地址从高到0 , 并且数据位于更高的地址 。 但是 , 这可能会导致引用数据的WebAssembly代码占用更多字节 , 因为地址是使用可变长度“ LEB”编码编写的 , 更有利于短偏移量 。
无论如何!walloc管理的内存上限是内存的总大小 , 该大小在64 KB的边界上对齐 。 Walloc也以64 KB页面管理内存 。 它从最初分配给模块的任何内存开始 , 如果内存用完 , 将扩展内存 。 主机可以指定最大内存大小(以页为单位) 。 如果没有更多页面可用 , walloc的malloc将仅返回NULL;处理内存不足问题丢给调用者解决 。
Walloc两种分配策略:小对象和大对象 。 大对象大对象超过256个字节 。
有可用的大型对象的全局空闲列表 , 每个对象都有一个标头 , 指示其大小 。 分配时 , walloc会通过该列表进行最合适大小的搜索 。
struct large_object {struct large_object * next;size_t size;char payload[0]; }; struct large_object * large_object_free_list;大型对象分配都向上舍入为256个字节(包括标头)的边界 。
如果空闲列表上没有对象可以满足分配 , walloc将按分配大小或当前walloc堆大小的一半(以较大者为准)的扩展堆 。 生成的页面构成一个可以满足分配要求的大对象 。
如果自由列表上的最佳对象的末尾有多个空间 , 则将其拆分 , 然后将尾巴放回自由列表 。 每块是256个字节 。
程序员效率工具:Walloc文章插图
每个页面为65536字节 , 每个块为256字节 , 因此页面中有256个块 。 从分配的对象开始(大小)的页面中的第一个块包含标题块 。 页面标头为页面中的256个块中的每个块都有一个字节 。 如果相应的块开始一个大对象 , 则该字节为255;否则 , 该字节指示打包的小对象分配的大小类(参见下图) 。
程序员效率工具:Walloc文章插图
拆分大对象时 , 我们避免在页面标题块上启动新的大对象 。 如果大对象包括整个页面 , 则只能绕过页面标题块所在的位置 。
释放大对象会将其推入全局空闲列表 。 通过查看页眉 , 知道指针是一个大对象 , 知道分配的大小 , 因为大对象标头位于分配之前 。 当释放后进行下一个大对象分配时 , 将通过合并相邻的大对象来压缩空闲对象列表 。


推荐阅读