jemalloc参数lg_prof_sample对内存影响

lg_prof_sample 是一个 对采样频率的对数设置:

lg_prof_sample = 0 表示:每次 malloc 都采样
lg_prof_sample = 22 表示:每约 4MB malloc 采样一次

测试程序,会有几千万次的new和delete,构造老对象;然后析构老对象,创建新对象

不带环境变量
image

带环境变量
RES最高50GB,之后稳定2.3g
env MALLOC_CONF="prof:true,prof_active:true,lg_prof_sample:0,prof_prefix:/tmp/profdump"
image

RES最高3GB,之后稳定240M
env MALLOC_CONF="prof:true,prof_active:true,lg_prof_sample:22,prof_prefix:/tmp/profdump"
image

你运行了同一个 C++ 程序,使用 jemalloc 的 heap profiling,结果如下:

lg_prof_sample 稳定期 RES 稳定期 VIRT 峰值 RES
0(等于强制采样) 2.3 GB 251 GB 50 GB
22(稀疏采样) 230 MB 1.3 GB 小很多

这个结果的根本原因是:开启 heap profiling 且采样频率高,会引入极大的元数据开销,jemalloc 需要额外的虚拟内存管理结构来记录每一个分配点的信息。

为什么 lg_prof_sample=0 会导致 251GB 的虚拟内存?

  1. 每次 malloc 都要采样,开销极高
    每次采样时,jemalloc 会保存一个 回溯栈(backtrace),并为这个 backtrace 生成一个新的 profile context。

这些 backtrace 和上下文信息不会被合并或去重(为了精确分析),而是分别保存。

  1. profile 栈帧信息本身也用 malloc 分配,形成内存放大
    采样频率过高导致 profile 信息堆积。

这些信息本身还会被再次采样(因为采样发生在 malloc 上),形成反馈链,越积越多。

这会造成两个后果:

RES 增高:因为堆积了大量 profile metadata(活跃内存)

VIRT 爆炸:jemalloc 为 profile 系统大量预留了虚拟地址空间(非物理内存),profiling 使用了大量 hashmap 和 trie 结构,追踪每个 allocation 栈帧

为了线程安全和性能,这些结构预留了大量空间(虽然未真正占用物理内存)

lg_prof_sample:0对内存影响很大。建议lg_prof_sample:22,即每4M采样一次,对进程影响小

虽然RES显示2.3g,不过profdump然后jeprof火焰图显示只有248MB,pmap显示是2.3g

带prof调试内存泄漏问题时,如果看到内存上涨很快,并不能说明程序泄漏也这么快,因为开启prof会有放大,尤其是如果设置lg_prof_sample:0放大非常严重

posted @ 2025-08-06 12:10  LdreamerD  阅读(56)  评论(0)    收藏  举报