1 个不稳定版本

0.2.1 2024年6月28日

#234 in 内存管理

MIT 许可证

24KB
518

Rheaper

Rheaper 是一个 Rust 的进程内堆分析器,它替换原有功能并收集分配数据,之后将其存储在 SQLite 数据库中进行分析。它支持运行时激活/去激活。

要使项目中的 heaptrack 可用,设置全局分配器

#[global_allocator]
static GLOBAL: Rheaper::Allocator<mimalloc::MiMalloc> =
    rheaper::Allocator::from_allocator(mimalloc::MiMalloc);

在任何时候,都可以启用跟踪

let profile_path = rheaper::enable_tracking(Rheaper::TrackerConfig {
    /// how deep should the call stack be sampled
    max_stack_depth: 30,
    /// each thread that allocates acquire a local tracker from the global pool. That's how many trackers can be created
    max_trackers: 200,
    /// How many alloc events are buffered per local tracker
    tracker_event_buffer_size: 5_000,
    /// How often to sample backtraces, 1.0 is always, 0.0 is never.
    sample_rate: 1.0,
    /// where th profile will be written
    profile_dir: PathBuf::new(),
});

使用以下命令停止记录

rheaper::disable_tracking();

这将解决挂起的回溯,并将分析数据刷新到磁盘。之后,可以分析配置文件

rheaper rip-4744532 profile.db

这将创建一个 profile.db sqlite 数据库。可以使用 sqlite 打开此数据库进行数据分析。

示例

显示按调用位置排序的前10大贡献者

SELECT bt, sum(size) FROM allocations GROUP BY bt ORDER BY sum(size) DESC LIMIT 10;

bt                    sum(size)
--------------------  ---------
14887427388493581654  61044456
6831336122721510729   52678176
2113490791341760087   52678176
15757739337697011469  31692912
3437328128932597320   24435936
15830995416840919940  10029120
7763277092675977093   9981504
10258202288105587101  9981504
12697966346495929209  3928320
4493127380101385995   3883680

显示生存时间超过10秒的调用位置的分配

SELECT bt, count(0), sum(size) FROM allocations where dealloc_after NOT NULL AND dealloc_after - alloc_after < 10000 GROUP BY bt ORDER BY sum(size) DESC LIMIT 5;

bt                    count(0)  sum(size)
--------------------  --------  ---------
14887427388493581654  372       61044456
6831336122721510729   372       52678176
2113490791341760087   372       52678176
15757739337697011469  372       31692912
3437328128932597320   372       24435936

可以使用 bt 查询 backtraces table

select frame_no, sym from backtraces where id = '14887427388493581654' limit 10;                

frame_no  sym
--------  ------------------------------------------------------------
0         backtrace::backtrace::libunwind::trace::h313fcf731c1ed43a

1         <rheaper::alloc::Allocator<A> as core::alloc::global::Glob
          alAlloc>::alloc::{{closure}}::hd945306712c35cdc

2         rheaper::alloc::with_local::{{closure}}::{{closure}}::{{cl
          osure}}::{{closure}}::h984dd2b94bca5c66

3         rheaper::alloc::TrackerGuard::with::h2f7bcd4120d6efa7

4         rheaper::alloc::with_local::{{closure}}::{{closure}}::{{cl
          osure}}::h51d6f70563022314

5         std::thread::local::LocalKey<T>::try_with::hff003d76feecb4a9

6         rheaper::alloc::with_local::{{closure}}::{{closure}}::h233
          b8e1d7f3eb3c5

7         rheaper::alloc::untracked::{{closure}}::hc0fb5ce1fd3deaf9

8         std::thread::local::LocalKey<T>::try_with::h8850e1a558f39df6

9         std::thread::local::LocalKey<T>::with::hcab5ce8347c6de7c

依赖项

~6–16MB
~213K SLoC