jemalloc参数lg_prof_sample对内存影响
lg_prof_sample 是一个 对采样频率的对数设置:
lg_prof_sample = 0 表示:每次 malloc 都采样
lg_prof_sample = 22 表示:每约 4MB malloc 采样一次
测试程序,会有几千万次的new和delete,构造老对象;然后析构老对象,创建新对象
不带环境变量

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

RES最高3GB,之后稳定240M
env MALLOC_CONF="prof:true,prof_active:true,lg_prof_sample:22,prof_prefix:/tmp/profdump"
![]()
你运行了同一个 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 的虚拟内存?
- 每次 malloc 都要采样,开销极高
每次采样时,jemalloc 会保存一个 回溯栈(backtrace),并为这个 backtrace 生成一个新的 profile context。
这些 backtrace 和上下文信息不会被合并或去重(为了精确分析),而是分别保存。
- 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放大非常严重

浙公网安备 33010602011771号