< 返回版块

js2xxx 发表于 2024-02-17 22:29

Tags:内存管理,无锁,并发,no_std,嵌入式

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变量的。如果条件不允许,或者想要更多的自定义空间,可以直接使用内部的结构体(ArenasContextHeap):

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, ContextHeap
  • "stat":统计内存分配数据;
  • "base-static":默认的静态内存基础分配器Static;
  • "base-mmap":使用OS自带的虚拟内存系列函数来获取新内存的基础分配器Mmap(依赖std);
  • "global"config!config_mod!等配置宏(自带的TLS变量默认会被泄露);
  • "libc": libc依赖项(被config!系列宏的pthread选项依赖,目的是使用pthread的TLS变量析构器来析构config!生成的TLS变量);
  • "default":默认的Ferroc分配器,基于Mmappthread选项(包括以上所有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处理器的笔记本电脑上运行。

花费时间: Time consumed

内存占用: Memory consumed

缺点

目前仅支持最新的Nightly通道的Rust编译器,并且malloc-bench中其他的一部分测试还尚未跑通。

许可证

MIT OR Apache-2.0


Ext Link: https://github.com/js2xxx/ferroc/

评论区

写评论

还没有评论

1 共 0 条评论, 1 页