内部碎片是什么
内存分配器按尺寸分级分配:请求 20 字节可能实际占 32 字节,多出来的部分就是内部碎片,也称分配粒度损耗。它与外部碎片不是一回事——外部碎片是页级闲置,内部碎片是舍入损耗。单个对象多几字节不起眼,但海量小键会把这点损耗累积成可观的内存占用。
基本信息
| 来源 | 分配器按尺寸分级舍入 |
|---|---|
| 观测命令 | MEMORY MALLOC-STATS(依赖 jemalloc 构建) |
| 结构化字段 | MEMORY STATS 里的分配器已分配与活跃量 |
| 与外部碎片区别 | 内部是分配粒度损耗,外部是页级闲置 |
| 放大条件 | 对象数量多且尺寸分散 |
| 缓解方向 | 聚合小对象、缩短键名、减少海量超小键 |
典型使用场景
- 内存对账:实际占用远大于业务估算时,先怀疑分配粒度损耗
- 海量小键治理:键多值小时,对象头与舍入损耗常常比数据本身更大
- 结构改造评估:把散键改成 hash 聚合后对比前后内存
- 版本升级核对:内存优化随版本变化,升级后重新建立基线
- 缓慢上涨排查:键数缓慢增长时损耗同步增长,要按对象数估算
最小示例
最小示例
redis-cli MEMORY MALLOC-STATS # 分配器分桶统计(依赖 jemalloc 构建)
redis-cli MEMORY STATS | grep -A1 allocator # 已分配量与活跃量
redis-cli INFO memory | grep -E 'used_memory_human|used_memory_rss_human|mem_fragmentation_ratio'
redis-cli DBSIZE # 键数量,用于估算对象规模
redis-cli MEMORY USAGE some:typical:key # 单键真实占用,与业务估算对照口径对照
| 对比 | 含义 | 说明 |
|---|---|---|
| 已用内存与分配器已分配量 | 分配器舍入带来的损耗 | 对象越多越明显 |
| 分配器已分配与活跃量 | 已分配但尚未使用的空间 | 与分配释放模式有关 |
| 已用内存与进程常驻内存 | 进程实际占用的物理内存 | 还包含页与页表等开销 |
| 业务估算与单键实测 | 键名与对象头开销 | 小对象场景差距最明显 |
内部碎片是分配粒度的必然结果,不是配置问题;治理方向是减少对象数量(聚合),而不是去调分配器参数。
MEMORY MALLOC-STATS 依赖 jemalloc:用其他分配器构建时该命令不可用,此时改用 MEMORY STATS 的分配器字段做近似判断。