Ferroc(由“ferrum”和“malloc”组合而成)是一个用Rust编写的无锁、可移植的堆内存分配器,主要参考了mimalloc。
这个内存分配器的设计目标是性能打平目前各种主流的内存分配器(如mimalloc,tcmalloc等),同时提供多种多样的自定义配置以移植到各种环境,比如裸机、嵌入式平台等。
目前已经在crates.io上发布。
示例
最简单的用途是作为全局内存分配器:
use ferroc::Ferroc;
#[global_allocator]
static FERROC: Ferroc = Ferroc;
fn main() {
// Using the global allocator API.
let _vec = vec![10; 100];
// Manually allocate memory.
let layout = std::alloc::Layout::new::<u8>();
let ptr = Ferroc.allocate(layout).unwrap();
unsafe { Ferroc.deallocate(ptr, layout) };
// Immediately run some delayed clean-up operations.
Ferroc.collect(/* force */false);
}
如果想要一些自定义配置,比如从mmap系统调用获取新内存还是仅分配静态内存,则可以使用config!
系列宏:
// This is the capacity of the necessary additional static
// memory space used by ferroc as the metadata storage.
const HEADER_CAP: usize = 4096;
ferroc::config!(pub Custom => ferroc::base::Static::<HEADER_CAP>);
#[global_allocator]
static CUSTOM: Custom = Custom;
// Multiple manageable static memory chunks can be loaded at runtime.
let chunk = unsafe { Chunk::from_static(/* ... */) };
CUSTOM.manage(chunk);
// ...And you can start allocation.
let _vec = vec![10; 100];
config!
系列宏配置出的分配器默认是带着TLS变量的。如果条件不允许,或者想要更多的自定义空间,可以直接使用内部的结构体(Arenas
、Context
、Heap
):
ferroc = {version = "*", default-features = false, features = ["base-mmap"]}
#![feature(allocator_api)]
use ferroc::{
arena::Arenas,
heap::{Heap, Context},
base::Mmap,
};
fn main() {
let arenas = Arenas::new(Mmap); // `Arenas` are `Send` & `Sync`...
let cx = Context::new(&arenas);
let heap = Heap::new(&cx); // ...while `Context`s and `Heap`s are not.
// Using the allocator API.
let mut vec = Vec::new_in(&heap);
vec.extend([1, 2, 3, 4]);
assert_eq!(vec.iter().sum::<i32>(), 10);
// Manually allocate memory.
let layout = std::alloc::Layout::new::<u8>();
let ptr = heap.allocate(layout).unwrap();
unsafe { heap.deallocate(ptr, layout) };
// Immediately run some delayed clean-up operations.
heap.collect(/* force */false);
}
Cargo功能列表
- 基本功能包含公开的结构体
Arenas
,Context
和Heap
; "stat"
:统计内存分配数据;"base-static"
:默认的静态内存基础分配器Static
;"base-mmap"
:使用OS自带的虚拟内存系列函数来获取新内存的基础分配器Mmap
(依赖std
);"global"
:config!
和config_mod!
等配置宏(自带的TLS变量默认会被泄露);"libc"
:libc
依赖项(被config!
系列宏的pthread
选项依赖,目的是使用pthread的TLS变量析构器来析构config!
生成的TLS变量);"default"
:默认的Ferroc
分配器,基于Mmap
和pthread
选项(包括以上所有feature);"c"
:生成fe_malloc
等C系列函数和一个C/C++头文件"ferroc.h"
,并且如果编译时指定了--cfg sys_alloc
会替换掉默认的malloc
系列函数;"track-valgrind"
:基于crabgrind
的Valgrind内存跟踪检查器.
基准测试
基准测试使用mimalloc-bench
的一部分子集。在我的16GB内存和Intel i7-10750H CPU @ 2.60GHz处理器的笔记本电脑上运行。
花费时间:
内存占用:
缺点
目前仅支持最新的Nightly通道的Rust编译器,并且malloc-bench
中其他的一部分测试还尚未跑通。
许可证
MIT OR Apache-2.0
Ext Link: https://github.com/js2xxx/ferroc/
1
共 0 条评论, 1 页
评论区
写评论还没有评论