如何追踪Rust程序内存使用?引入memory-stats库遇编译错误
解决memory-stats库在macOS下的编译错误问题
问题背景
对Rust了解不多,想查看Rust程序的当前内存使用情况,引入memory-stats库后,编译时出现以下错误:
Compiling memory-stats v1.1.0 error[E0432]: unresolved imports `libc::mach_task_basic_info_data_t`, `libc::mach_task_self`, `libc::task_info`, `libc::task_info_t`, `libc::MACH_TASK_BASIC_INFO`, `libc::MACH_TASK_BASIC_INFO_COUNT` --> /Users/meij/.cargo/registry/src/index.crates.io-6f17d22bba15001f/memory-stats-1.1.0/src/darwin.rs:4:29 | 4 | mach_msg_type_number_t, mach_task_basic_info_data_t, mach_task_self, task_info, task_info_t, K... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^ no `task_info_t` in the root | | | | | | | no `task_info` in the root | | no `mach_task_self` in the root | no `mach_task_basic_info_data_t` in the root 5 | MACH_TASK_BASIC_INFO, MACH_TASK_BASIC_INFO_COUNT, | ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `MACH_TASK_BASIC_INFO_COUNT` in the root | | | no `MACH_TASK_BASIC_INFO` in the root | help: a similar name exists in the module | 4 | mach_msg_type_number_t, mach_timebase_info_data_t, mach_task_self, task_info, task_info_t, KERN_SUCCESS, | ~~~~~~~~~~~~~~~~~~~~~~~~~ help: a similar name exists in the module | 4 | mach_msg_type_number_t, mach_task_basic_info_data_t, mach_host_self, task_info, task_info_t, KERN_SUCCESS, | ~~~~~~~~~~~~~~ For more information about this error, try `rustc --explain E0432`. error: could not compile `memory-stats` (lib) due to previous error
本地环境版本:
- rustc 1.72.1 (d5c2e9c34 2023-09-13)
- cargo 1.72.1 (103a7ff2e 2023-08-15)
原因分析
这个错误是因为memory-stats v1.1.0的macOS平台实现依赖的libc版本较旧,而新版libc中macOS的mach相关API命名或结构发生了变化,导致库无法找到对应的导入项。
解决方法
方案1:指定兼容的libc版本
在Cargo.toml中明确指定与memory-stats v1.1.0兼容的libc版本:
[dependencies] memory-stats = "1.1.0" libc = "0.2.146"
然后执行以下命令重新编译:
cargo clean && cargo build
方案2:改用更活跃的跨平台库
如果方案1无效,推荐使用sysinfo库,它跨平台支持,API更友好,能获取内存、CPU等多种系统信息:
- 在
Cargo.toml中添加依赖:
[dependencies] sysinfo = "0.29"
- 示例代码:
use sysinfo::{System, SystemExt}; fn main() { let mut sys = System::new_all(); sys.refresh_memory(); println!("当前程序内存使用: {} KB", sys.used_memory()); println!("系统总内存: {} KB", sys.total_memory()); }
方案3:手动实现macOS内存监控
如果不想依赖第三方库,可以直接调用mach API实现内存监控,示例代码如下:
- 先在
Cargo.toml中添加libc依赖:
[dependencies] libc = "0.2"
- 实现代码:
#[cfg(target_os = "macos")] fn get_memory_usage() -> Option<u64> { use libc::{c_int, c_void, mach_msg_type_number_t}; const MACH_TASK_BASIC_INFO: c_int = 4; const MACH_TASK_BASIC_INFO_COUNT: mach_msg_type_number_t = 6; type MachTaskBasicInfo = [u64; MACH_TASK_BASIC_INFO_COUNT as usize]; unsafe { let mut info = MachTaskBasicInfo::default(); let mut count = MACH_TASK_BASIC_INFO_COUNT; let task = libc::mach_task_self(); let ret = libc::task_info( task, MACH_TASK_BASIC_INFO, &mut info as *mut _ as *mut c_void, &mut count, ); if ret == libc::KERN_SUCCESS { Some(info[0]) // 返回常驻内存大小(字节) } else { None } } } #[cfg(target_os = "macos")] fn main() { match get_memory_usage() { Some(mem_bytes) => println!("当前内存使用: {} MB", mem_bytes / 1024 / 1024), None => println!("无法获取内存使用信息"), } }
内容的提问来源于stack exchange,提问作者May
相关产品推荐
相关产品推荐

