M1芯片macOS13.4下Rust用jemalloc生成内存快照报错求助
我在搭载M1芯片的macOS 13.4系统中,尝试通过以下Rust代码使用jemalloc生成内存快照:
use jemalloc_ctl::{AsName, Access}; use std::collections::HashMap; #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; const PROF_ACTIVE: &'static [u8] = b"prof.active\0"; const PROF_DUMP: &'static [u8] = b"prof.dump\0"; const PROFILE_OUTPUT: &'static [u8] = b"profile.out\0"; fn set_prof_active(active: bool) { let name = PROF_ACTIVE.name(); name.write(active).expect("Should succeed to set prof"); } fn dump_profile() { let name = PROF_DUMP.name(); name.write(PROFILE_OUTPUT).expect("Should succeed to dump profile") } fn main() { set_prof_active(true); let mut buffers: Vec<HashMap<i32, i32>> = Vec::new(); for _ in 0..100 { buffers.push(HashMap::with_capacity(1024)); } set_prof_active(false); dump_profile(); }
运行后触发如下错误:
thread 'main' panicked at src/main.rs:18:32: Should succeed to dump profile: An interface with side effects failed in some way not directly related to `mallctl*()` read/write processing. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
请问jemalloc是否不支持macOS?还是我遗漏了相关配置?以下是项目的Cargo.toml配置:
[package] name = "rust-learn" version = "0.1.0" edition = "2018" [dependencies] jemallocator = "0.3.2" jemalloc-ctl = "0.3.2" [dependencies.jemalloc-sys] version = "0.3.2" features = ["stats", "profiling", "unprefixed_malloc_on_supported_platforms"] [profile.release] debug = true
当前使用的Rust版本信息:
➜ rust-learn git:(rustflags) ✗ rustup -V rustup 1.27.1 (54dd3d00f 2024-04-24) info: This is the version for the rustup toolchain manager, not the rustc compiler. info: The currently active `rustc` version is `rustc 1.79.0 (129f3b996 2024-06-10)
问题原因与解决方案
jemalloc本身支持macOS(包括M1架构),你的问题主要出在配置和使用方式上:
1. 依赖版本过旧
你使用的jemallocator系列依赖版本为0.3.2,这个版本对Apple Silicon的支持不完善,存在profiling相关的兼容性bug。建议升级到最新稳定版(截至2024年8月,最新版为0.5.4),新版本对M1 macOS的适配更好。
2. 动态启用profiling时机错误
jemalloc的profiling模块需要在进程启动时初始化,而非运行时动态开启。你在main函数中才调用set_prof_active(true),会导致profiling无法正常捕获内存分配数据,最终dump失败。
3. 缺少必要的初始化配置
在Apple Silicon macOS上使用profiling功能,需要通过环境变量确保jemalloc正确初始化profiling模块。
具体修复步骤
步骤1:升级依赖版本
修改Cargo.toml中的依赖配置:
[package] name = "rust-learn" version = "0.1.0" edition = "2018" [dependencies] jemallocator = "0.5.4" jemalloc-ctl = "0.5.4" [dependencies.jemalloc-sys] version = "0.5.4" features = ["stats", "profiling"] [profile.release] debug = true
移除unprefixed_malloc_on_supported_platforms特性,新版本无需该配置
步骤2:通过环境变量启用profiling
移除代码中动态设置prof.active的逻辑,改为运行程序前设置环境变量:
export MALLOC_CONF="prof_active:true"
步骤3:调整代码dump逻辑
修改dump_profile函数,使用jemalloc_ctl::raw模块直接调用底层接口:
use jemalloc_ctl::raw; use std::collections::HashMap; #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; fn dump_profile() { raw::write(b"prof.dump\0", b"profile.out\0").expect("Failed to dump profile"); } fn main() { let mut buffers: Vec<HashMap<i32, i32>> = Vec::new(); for _ in 0..100 { buffers.push(HashMap::with_capacity(1024)); } dump_profile(); }
步骤4:运行程序
执行以下命令运行程序,生成内存快照:
export MALLOC_CONF="prof_active:true" cargo run --release
运行完成后,当前目录会生成profile.out文件,可使用jemalloc自带的jeprof工具分析快照:
jeprof target/release/rust-learn profile.out
额外注意事项
- 确保系统已安装Xcode Command Line Tools,否则jemalloc-sys可能无法正常编译;
- 若新版本jemalloc仍存在编译问题,可尝试设置
RUSTFLAGS="-C target-feature=+crt-static"强制静态链接。
内容的提问来源于stack exchange,提问作者Dolphin

