堆内存性能分析器

qianmoQqianmoQ· 更新于 2026-10-05· 阅读 11 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

堆内存分析(heap profiler)

了解 heap profiler 服务。

brpc 可以分析内存是被哪些函数占据的。heap profiler 的原理是每分配满一些内存就采样调用处的栈,“一些”由环境变量 TCMALLOC_SAMPLE_PARAMETER 控制,默认 524288,即 512K 字节。根据栈表现出的函数调用关系汇总为我们看到的结果图。在实践中 heap profiler 对原程序的影响不明显。

开启方法

  1. 链接libtcmalloc_and_profiler.a

    1. 如果 tcmalloc 使用 frame pointer 而不是 libunwind 回溯栈,请确保在 CXXFLAGS 或 CFLAGS 中加上-fno-omit-frame-pointer,否则函数间的调用关系会丢失,最后产生的图片中都是彼此独立的函数方框。
  2. 在 shell 中export TCMALLOC_SAMPLE_PARAMETER=524288。该变量指每分配这么多字节内存时做一次统计,默认为 0,代表不开启内存统计。官方文档]建议设置为 524288。这个变量也可在运行前临时设置,如TCMALLOC_SAMPLE_PARAMETER=524288 ./server。如果没有这个环境变量,可能会看到这样的结果:

    $ tools/pprof --text localhost:9002/pprof/heap
    Fetching /pprof/heap profile from http://localhost:9002/pprof/heap to
      /home/gejun/pprof/echo_server.1419559063.localhost.pprof.heap
    Wrote profile to /home/gejun/pprof/echo_server.1419559063.localhost.pprof.heap
    /home/gejun/pprof/echo_server.1419559063.localhost.pprof.heap: header size >= 2**16
  3. 如果只是 brpc client 或没有使用 brpc,看这里]。

注意要关闭 Server 端的认证,否则可能会看到这个:

$ tools/pprof --text localhost:9002/pprof/heap
Use of uninitialized value in substitution (s///) at tools/pprof line 2703.
http://localhost:9002/pprof/symbol doesn't exist

服务端可能会出现如下日志:

FATAL: 12-26 10:01:25:   * 0 [src/brpc/policy/giano_authenticator.cpp:65][4294969345] Giano fails to verify credentical, 70003
WARNING: 12-26 10:01:25:   * 0 [src/brpc/input_messenger.cpp:132][4294969345] Authentication failed, remote side(127.0.0.1:22989) of sockfd=5, close it

图示

img

左上角是当前程序通过 malloc 分配的内存总量,顺着箭头上的数字可以看到内存来自哪些函数。

点击左上角的 text 选择框可以查看文本格式的结果,有时候这种按分配量排序的形式更方便。

img

左上角的两个选择框作用分别是:

  • View:当前正在看的 profile。选择 <new profile> 表示新建一个。新建完毕后,View 选择框中会出现新 profile,URL 也会被修改为对应的地址。这意味着你可以通过粘贴 URL 分享结果,点击链接的人将看到和你一模一样的结果,而不是重新做一次 profiling 的结果。你可以在框中选择之前的 profile 查看。历史 profile 保留最近的 32 个,可通过 –max_profiles_kept](http://brpc.baidu.com:8765/flags/max_profiles_kept) 调整。
  • Diff:和选择的 profile 做对比。不选表示什么都不选。如果你选择了之前的某个 profile,那么将看到 View 框中的 profile 相比 Diff 框中 profile 的变化量。

下图演示了勾选 Diff 和 Text 的效果。

img

在 Linux 下,你也可以使用 pprof 脚本(tools/pprof)在命令行中查看文本格式结果:

$ tools/pprof --text db-rpc-dev00.db01:8765/pprof/heap
Fetching /pprof/heap profile from http://db-rpc-dev00.db01:8765/pprof/heap to
  /home/gejun/pprof/play_server.1453216025.db-rpc-dev00.db01.pprof.heap
Wrote profile to /home/gejun/pprof/play_server.1453216025.db-rpc-dev00.db01.pprof.heap
Adjusting heap profiles for 1-in-524288 sampling rate
Heap version 2
Total: 38.9 MB
    35.8  92.0%  92.0%     35.8  92.0% ::cpp_alloc
     2.1   5.4%  97.4%      2.1   5.4% butil::FlatMap
     0.5   1.3%  98.7%      0.5   1.3% butil::IOBuf::append
     0.5   1.3% 100.0%      0.5   1.3% butil::IOBufAsZeroCopyOutputStream::Next
     0.0   0.0% 100.0%      0.6   1.5% MallocExtension::GetHeapSample
     0.0   0.0% 100.0%      0.5   1.3% ProfileHandler::Init
     0.0   0.0% 100.0%      0.5   1.3% ProfileHandlerRegisterCallback
     0.0   0.0% 100.0%      0.5   1.3% __do_global_ctors_aux
     0.0   0.0% 100.0%      1.6   4.2% _end
     0.0   0.0% 100.0%      0.5   1.3% _init
     0.0   0.0% 100.0%      0.6   1.5% brpc::CloseIdleConnections
     0.0   0.0% 100.0%      1.1   2.9% brpc::GlobalUpdate
     0.0   0.0% 100.0%      0.6   1.5% brpc::PProfService::heap
     0.0   0.0% 100.0%      1.9   4.9% brpc::Socket::Create
     0.0   0.0% 100.0%      2.9   7.4% brpc::Socket::Write
     0.0   0.0% 100.0%      3.8   9.7% brpc::Span::CreateServerSpan
     0.0   0.0% 100.0%      1.4   3.5% brpc::SpanQueue::Push
     0.0   0.0% 100.0%      1.9   4.8% butil::ObjectPool
     0.0   0.0% 100.0%      0.8   2.0% butil::ResourcePool
     0.0   0.0% 100.0%      1.0   2.6% butil::iobuf::tls_block
     0.0   0.0% 100.0%      1.0   2.6% bthread::TimerThread::Bucket::schedule
     0.0   0.0% 100.0%      1.6   4.1% bthread::get_stack
     0.0   0.0% 100.0%      4.2  10.8% bthread_id_create
     0.0   0.0% 100.0%      1.1   2.9% bvar::Variable::describe_series_exposed
     0.0   0.0% 100.0%      1.0   2.6% bvar::detail::AgentGroup
     0.0   0.0% 100.0%      0.5   1.3% bvar::detail::Percentile::operator
     0.0   0.0% 100.0%      0.5   1.3% bvar::detail::PercentileSamples
     0.0   0.0% 100.0%      0.5   1.3% bvar::detail::Sampler::schedule
     0.0   0.0% 100.0%      6.5  16.8% leveldb::Arena::AllocateNewBlock
     0.0   0.0% 100.0%      0.5   1.3% leveldb::VersionSet::LogAndApply
     0.0   0.0% 100.0%      4.2  10.8% pthread_mutex_unlock
     0.0   0.0% 100.0%      0.5   1.3% pthread_once
     0.0   0.0% 100.0%      0.5   1.3% std::_Rb_tree
     0.0   0.0% 100.0%      1.5   3.9% std::basic_string
     0.0   0.0% 100.0%      3.5   9.0% std::string::_Rep::_S_create

brpc 还提供一个类似的 growth profiler,用于分析内存分配的去向(不考虑释放)。

img

MacOS 的额外配置

  1. 安装standalone pprof,并把下载的 pprof 二进制文件路径写入环境变量 GOOGLE_PPROF_BINARY_PATH 中
  2. 安装 llvm-symbolizer(将函数符号转化为函数名),直接用 brew 安装即可:brew install llvm

最后修改于 2022 年 5 月 17 日:更新 brpc 用户页面 (devlive-community/knowforge#71) (a31ce10d3)

评论

登录后参与评论

正在加载评论…