内存碎片化三
要分析 Slab 是否正常,可以从以下几个方面进行判断:
1. 对象使用率分析
-
Active / Total Objects (% used) :88.6%
-
说明当前分配的对象占比 88.6%,整体利用率较高。
-
如果接近 100%,可能意味着内存压力较大,可能需要增加 Slab 缓存或释放无用对象。
-
2. Slab 使用率分析
-
Active / Total Slabs (% used) :100.0%
-
Slab 使用率达到 100%,意味着所有分配的 Slab 都在使用,没有空闲的 Slab。
-
可能需要观察是否有 Slab 增长或者 slab 分配失败的情况(可以通过
dmesg或/proc/slabinfo进一步分析)。
-
3. Cache 使用率分析
-
Active / Total Caches (% used) :73.3%
-
73.3% 的 Cache 在使用中,剩余 26.7% 可用,属于正常范围。
-
如果 Cache 使用率过高(接近 100%),可能导致性能下降,建议优化缓存回收策略。
-
4. 内存使用率分析
-
Active / Total Size (% used) :90.6%
-
Slab 使用了 90.6% 的总分配内存,说明系统内存开销较大,但仍然有一定余量。
-
需要观察系统是否有
OOM(Out of Memory)风险,例如dmesg | grep -i oom检查是否发生 OOM 事件。
-
5. 对象大小分布
-
Minimum / Average / Maximum Object : 0.01K / 0.20K / 12.69K
-
最大对象大小 12.69K,最小对象 0.01K,平均 0.20K,说明对象大小分布较合理。
-
如果最大对象大小异常增大(如 >100K),可能表明有异常的 Slab 分配。可以进一步检查
cat /proc/slabinfo | sort -nk 3观察占用较大的 Slab 具体是哪些。
-
6. 进一步诊断
-
检查哪些 Slab 消耗最多内存:
cat /proc/slabinfo | sort -nk 3 | tail -n 20-
这条命令会列出消耗最多的 Slab 项,分析是否有异常的缓存项。
-
-
观察 Slab 增长趋势:
watch -n 1 cat /proc/slabinfo-
观察 Slab 是否不断增长,可能是某些服务或进程导致的。
-
-
检查特定的 Slab 分配问题:
slabtop-
slabtop可以实时监控 Slab 的使用情况,发现是否有异常的对象占用较多内存。
-
7. 是否正常的判断标准
| 指标 | 正常情况 | 异常情况 |
|---|---|---|
| Active / Total Objects | 60% - 90% | > 95% 可能有内存压力 |
| Active / Total Slabs | < 90% | 100% 可能需要扩展 |
| Active / Total Caches | 50% - 80% | < 30% 可能浪费资源,> 90% 可能有瓶颈 |
| Active / Total Size | < 85% | > 90% 可能需要优化 |
| 最大对象大小 | 适中(如 < 50K) | > 100K 可能有异常 |
8. 优化建议
-
如果 Slab 使用率高(> 90%),可以:
-
释放 Slab 缓存:
echo 3 > /proc/sys/vm/drop_caches -
检查是否有内存泄漏:
-
通过
slabtop观察是否有 Slab 项不断增长。
-
-
优化应用程序:
-
减少大对象的 Slab 分配(如避免频繁创建大数据结构)。
-
-
升级内存:
-
如果 Slab 长期处于 100%,可能需要增加物理内存。
-
-
你可以先执行 slabtop 和 cat /proc/slabinfo | sort -nk 3 | tail -n 20 看看具体哪些 Slab 使用率最高,然后我可以帮你分析具体情况。
如何判断是否有内存碎片(High-order Memory Fragmentation)
内存碎片的主要问题是,即使系统有足够的可用内存,仍然可能因为连续的大块物理内存(高阶页)无法分配而导致 OOM(Out of Memory)或分配失败。我们可以从以下几个方面分析内存碎片情况:
1. 查看 Buddy System 分配情况
Linux 内核使用 Buddy System 来管理物理内存,其中 高阶内存(High-order Memory) 指的是连续的 2ⁿ 个页面(4K/8K/16K/32K/…)。
可以使用以下命令查看各个阶(order)上的空闲页面情况:
cat /proc/buddyinfo
示例输出:
Node 0, zone DMA 1 1 1 1 0 0 0 0 0 0 0
Node 0, zone DMA32 1032 512 257 128 60 30 15 7 3 1 0
Node 0, zone Normal 20480 10240 5120 2560 1280 640 320 160 80 40 20
如何分析 /proc/buddyinfo
| Order | 内存块大小 | 作用 |
|---|---|---|
| 0 | 4K | 最小单位 |
| 1 | 8K | 2 个连续的 4K 页 |
| 2 | 16K | 4 个连续的 4K 页 |
| 3 | 32K | 8 个连续的 4K 页 |
| 4 | 64K | 16 个连续的 4K 页 |
| 5 | 128K | 32 个连续的 4K 页 |
| 6 | 256K | 64 个连续的 4K 页 |
| 7 | 512K | 128 个连续的 4K 页 |
| 8 | 1M | 256 个连续的 4K 页 |
| 9 | 2M | 512 个连续的 4K 页(HugePage 大小) |
| 10 | 4M | 1024 个连续的 4K 页 |
| 11 | 8M | 2048 个连续的 4K 页 |
判断碎片化的方法
-
低阶 order(0-2)可用内存较多,而高阶 order(>5)几乎没有
-
说明大块物理内存已经被打碎,系统可能需要频繁进行碎片整理(compaction)。
-
-
高阶内存(order > 9)长期为 0
-
可能导致无法分配 HugePage,影响大块内存分配需求(如数据库、缓存应用)。
-
-
如果 order 6-9 级别内存可用数量非常少,且大部分内存都在 order 0-2
-
说明系统存在严重的碎片化。
-
2. 检查 Slab 内存是否占用过多
Slab 缓存的内存如果不能及时回收,会导致可用的物理页变得零碎,增加碎片化的可能性。
查看 slab 消耗情况:
cat /proc/meminfo | grep Slab
示例输出:
Slab: 1874928 kB
SReclaimable: 924728 kB
SUnreclaim: 950200 kB
-
Slab(总 Slab 内存):1874928 KB -
SReclaimable(可回收 Slab):924728 KB(可通过drop_caches释放) -
SUnreclaim(不可回收 Slab):950200 KB(可能导致碎片)
如果 SUnreclaim 过高,说明系统有大量 Slab 内存无法释放,可能导致碎片化。
释放 Slab 缓存(仅影响 SReclaimable 部分):
echo 3 > /proc/sys/vm/drop_caches
3. 检查 HugePages 可用情况
如果 HugePages 申请失败,可能是由于高阶内存碎片化,导致无法分配 2M 或 1G 的大页面。
查看 HugePages:
cat /proc/meminfo | grep -i huge
示例:
HugePages_Total: 512
HugePages_Free: 10
HugePages_Rsvd: 5
HugePages_Surp: 0
-
HugePages_Free 过低(如 < 10):可能是高阶碎片化导致无法分配。
-
HugePages_Rsvd > 0:有部分 HugePages 预留但未使用。
-
解决方案:
-
调整 HugePages 配置:
echo 1024 > /proc/sys/vm/nr_hugepages -
或者重启应用释放 HugePages。
-
4. 使用 vmstat 检查内存碎片化
vmstat -s
示例输出:
16425400 K total memory
2204536 K used memory
840392 K active memory
420196 K inactive memory
14020864 K free memory
1052356 K buffer memory
3154960 K swap cache
15 K free high memory
14020864 K free low memory
重点关注:
-
free high memory过低:可能是高阶碎片化导致系统无法分配高阶内存。 -
free low memory过高但used memory低:说明有内存,但无法有效分配大块连续内存。
5. 使用 dmesg 检查内存分配失败
如果系统发生了高阶内存分配失败,dmesg 会有相关错误日志:
dmesg | grep -i "order"
示例错误:
page allocation failure: order:4, mode:0x104020
表示系统尝试申请 2^4 = 16K 连续内存失败,说明高阶碎片化严重。
6. 解决内存碎片化问题
如果确认有碎片化问题,可以尝试以下解决方案:
1. 手动触发内存整理(Compaction)
echo 1 > /proc/sys/vm/compact_memory
或者:
sysctl -w vm.compact_memory=1
这会触发 kcompactd 线程尝试整理内存,使高阶内存变得可用。
2. 关闭 Transparent HugePages(THP)
在某些情况下,THP 可能会加剧内存碎片化,可以尝试关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
3. 释放 Slab 和 PageCache
echo 3 > /proc/sys/vm/drop_caches
清理 PageCache 和可回收 Slab,减少碎片化。
4. 增加 HugePages
echo 512 > /proc/sys/vm/nr_hugepages
预留更多 HugePages,避免碎片化。
总结
| 检查项 | 正常情况 | 异常情况 |
|---|---|---|
/proc/buddyinfo |
高阶页面数量均衡 | 低阶数量多,高阶几乎为 0 |
| `/proc/meminfo | grep Slab` | SUnreclaim < 30% |
vmstat -s |
free high memory > 0 |
free high memory 过低 |
| `dmesg | grep order` | 无日志 |
你可以先执行 cat /proc/buddyinfo 和 dmesg | grep -i order 看看具体情况,我可以帮你进一步分析。
Linux Slab 和高阶内存碎片分析指南
1. Slab 分配情况分析
Slab 主要用于缓存小对象,分析是否正常可参考以下指标:
| 指标 | 正常情况 | 异常情况 |
|---|---|---|
| Active / Total Objects | 60% - 90% | > 95% 可能有内存压力 |
| Active / Total Slabs | < 90% | 100% 可能需要扩展 |
| Active / Total Caches | 50% - 80% | < 30% 可能浪费资源,> 90% 可能有瓶颈 |
| Active / Total Size | < 85% | > 90% 可能需要优化 |
| 最大对象大小 | 适中(如 < 50K) | > 100K 可能有异常 |
2. 检查 Slab 详情
cat /proc/slabinfo | sort -nk 3 | tail -n 20
可以看到占用最多的 Slab 项目,并判断是否有异常的缓存占用。
3. 释放 Slab 缓存
echo 3 > /proc/sys/vm/drop_caches
仅释放 SReclaimable 部分的 Slab,不会影响 SUnreclaim。
内存碎片(高阶内存)分析
高阶内存(High-order Memory)指连续的 2ⁿ 个 4K 页面,如 8K、16K、32K 等。
1. 查看 Buddy System 内存分配情况
cat /proc/buddyinfo
示例:
Node 0, zone Normal 20480 10240 5120 2560 1280 640 320 160 80 40 20
判断方法:
-
低阶(order 0-2)内存多,高阶(order > 5)几乎为 0 → 碎片化严重
-
高阶内存分配失败(order > 9 长期为 0) → 影响 HugePage、大块内存分配
2. 检查 HugePages 是否受影响
cat /proc/meminfo | grep -i huge
如果 HugePages_Free 过低,可能是碎片化导致无法分配大块内存。
3. 使用 vmstat 检查内存碎片
vmstat -s
-
free high memory过低:碎片化严重 -
free low memory过高但used memory低:有内存但无法分配大块连续内存
4. 检查内存分配失败日志
dmesg | grep -i "order"
示例:
page allocation failure: order:4, mode:0x104020
说明高阶内存分配失败。
解决方案
1. 手动整理内存(Compaction)
echo 1 > /proc/sys/vm/compact_memory
2. 释放 Slab 和 PageCache
echo 3 > /proc/sys/vm/drop_caches
3. 关闭 Transparent HugePages
echo never > /sys/kernel/mm/transparent_hugepage/enabled
4. 预留更多 HugePages
echo 512 > /proc/sys/vm/nr_hugepages
总结
| 检查项 | 正常情况 | 异常情况 |
|---|---|---|
/proc/buddyinfo |
高阶页面数量均衡 | 高阶几乎为 0 |
| `/proc/meminfo | grep Slab` | SUnreclaim < 30% |
vmstat -s |
free high memory > 0 |
free high memory 过低 |
| `dmesg | grep order` | 无日志 |
建议:先执行 cat /proc/buddyinfo 和 dmesg | grep -i order,根据输出情况进行进一步分析。
浙公网安备 33010602011771号