Rust中使用jemalloc动态开启内存分析报错,求解决方案
使用jemalloc检测Rust程序内存泄漏的配置问题
我想用jemalloc检测Rust程序的内存泄漏,需要生成dump文件并通过外部接口动态控制生成。操作步骤如下:
- 在Cargo.toml中添加依赖:
[package] name = "rust-learn" version = "0.1.0" edition = "2018" [dependencies] tokio = { version = "1.17.0", features = ["full"] } actix-web = "4" serde = { version = "1.0.64", features = ["derive"] } serde_json = "1.0.64" log4rs = "1.2.0" jemallocator = "0.5.4" jemalloc-ctl = "0.5.4" [dependencies.jemalloc-sys] version = "0.5.4" features = ["stats", "profiling", "unprefixed_malloc_on_supported_platforms"] [profile.release] debug = true [build-dependencies]
- 在main.rs中编写控制分析开关的HTTP接口:
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder}; use jemalloc_ctl::{AsName, Access}; #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; const PROF_ACTIVE: &'static [u8] = b"prof.active\0"; #[get("/active")] async fn hello() -> impl Responder { let name = PROF_ACTIVE.name(); name.write(true).expect("Should succeed to set prof"); HttpResponse::Ok().body("Hello, world!") } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .service(hello) }) .bind("127.0.0.1:8080")? .run() .await }
- 调用接口时出现错误:
执行curl http://127.0.0.1:8080/active返回curl: (52) Empty reply from server,服务端报错:
thread 'actix-rt|system:0|arbiter:1' panicked at src/main.rs:17:22: Should succeed to set prof: `name` or `mib` specifies an unknown/invalid value. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
环境信息:macOS 13.3.1,Rust 1.73。尝试在.cargo/config.toml添加MALLOC_CONF="prof:true",问题仍未解决。
修复方案
错误核心原因是jemalloc的profiling功能未在初始化阶段启用,导致运行时无法访问prof.active配置项。以下是具体修复步骤:
1. 确保jemalloc-sys的profiling特性正确激活
在jemalloc-sys依赖中添加default-features = false,避免默认特性覆盖自定义配置:
[dependencies.jemalloc-sys] version = "0.5.4" features = ["stats", "profiling", "unprefixed_malloc_on_supported_platforms"] default-features = false
2. 在程序启动时启用profiling
.cargo/config.toml的环境变量可能未正确传递,建议通过启动命令或代码初始化配置:
方式一:启动时手动设置环境变量
运行程序时执行:
MALLOC_CONF="prof:true,prof_prefix:jeprof" cargo run --release
prof:true:启用profiling功能prof_prefix:jeprof:指定dump文件前缀,方便后续分析
方式二:代码中初始化配置
在main函数开头添加初始化代码,确保profiling在启动时生效:
use jemalloc_ctl::config; #[actix_web::main] async fn main() -> std::io::Result<()> { // 初始化jemalloc profiling配置 let _ = config::prof::true_().write(true); let _ = config::prof::prefix::write("jeprof"); HttpServer::new(|| { App::new() .service(hello) }) .bind("127.0.0.1:8080")? .run() .await }
3. 修正prof.active的访问方式
使用jemalloc_ctl提供的类型安全API替代字节数组构造,避免配置项名称错误:
use jemalloc_ctl::prof; #[get("/active")] async fn hello() -> impl Responder { // 激活profiling prof::active::write(true).expect("Failed to activate profiling"); // 立即生成dump文件 prof::dump::write(true).expect("Failed to generate dump"); HttpResponse::Ok().body("Profiling activated and dump generated!") }
4. 验证dump文件生成
调用接口后,程序运行目录会生成类似jeprof.<pid>.0.f.heap的dump文件,使用jeprof工具分析:
jeprof --show_bytes ./target/release/rust-learn jeprof.<pid>.0.f.heap
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

