内存碎片化三

要分析 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%),可以:

    1. 释放 Slab 缓存

      echo 3 > /proc/sys/vm/drop_caches
      
    2. 检查是否有内存泄漏

      • 通过 slabtop 观察是否有 Slab 项不断增长。

    3. 优化应用程序

      • 减少大对象的 Slab 分配(如避免频繁创建大数据结构)。

    4. 升级内存

      • 如果 Slab 长期处于 100%,可能需要增加物理内存。

你可以先执行 slabtopcat /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/buddyinfodmesg | 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/buddyinfodmesg | grep -i order,根据输出情况进行进一步分析。

posted on 2025-03-31 17:35  吃草的青蛙  阅读(278)  评论(0)    收藏  举报

导航