如何开机运行memstrack分析内核模块内存,或推荐替代工具
解决内核模块内存监控及开机记录问题
核心需求
实时查看所有内核模块当前内存占用,同时记录开机阶段内核模块加载时的内存使用情况。
已遇问题梳理
- memstrack仅支持运行时数据收集,无法覆盖开机早期阶段;dracut目录下的memstrack模块不知如何配置使用
memstrack.service在systemd日志显示执行成功,但systemctl status memstrack.service提示找不到单元- 向grub配置添加
rd.memdebug=4后,开机检查/proc/cmdline未发现该参数 - memstrack仅在系统崩溃时(需在
/etc/sysconfig/kdump的KDUMP_COMMANDLINE_APPEND中添加rd.memdebug=[4,5])生成报告,开机cron任务运行memstrack的结果与实际差异极大(如ice模块手动加载卸载显示占用5GB,但memstrack报告不符) - 尝试过slabinfo,不符合需求
解决方案
一、实时监控内核模块内存的工具推荐
1. smem
smem是一款高级内存统计工具,可精准统计内核模块的内存占用(包括RSS、PSS等维度),比lsmod更贴近真实内存使用:
- 安装:
yum install smem(CentOS/RHEL)或apt install smem(Debian/Ubuntu) - 查看内核模块内存:
smem -t -k -u -m,其中-m选项专门展示内核模块的内存统计
2. /proc/modules + 计算脚本
直接读取/proc/modules文件,结合页大小计算模块实际内存占用:
- 每页大小可通过
getconf PAGE_SIZE获取(通常为4096字节) - 示例脚本:
#!/bin/bash PAGE_SIZE=$(getconf PAGE_SIZE) echo "模块名 内存占用(MB)" while read name size rest; do echo "$name $((size * PAGE_SIZE / 1024 / 1024))" done < /proc/modules | sort -k2 -nr
3. eBPF/bpftrace脚本
若需要跟踪模块运行时的动态内存分配(如kmalloc/vmalloc),可使用bpftrace编写简单脚本统计:
- 示例脚本(统计每个模块的kmalloc调用次数及字节数):
kprobe:kmalloc { @alloc[comm, kstack(10)] = sum(arg2); }
运行:bpftrace ./module-malloc.bt,可实时看到各模块的内存分配情况
4. kmtrace(内核级跟踪)
若内核开启了CONFIG_KMEMTRACE配置,可使用kmtrace跟踪模块的内存分配与释放,需编译内核时开启该选项,适合深度调试场景
二、解决开机阶段内存记录问题
1. 修复grub参数不生效问题
- 编辑
/etc/default/grub,在GRUB_CMDLINE_LINUX后添加rd.memdebug=4 - 重新生成grub配置:
- CentOS/RHEL:
grub2-mkconfig -o /boot/grub2/grub.cfg - Debian/Ubuntu:
update-grub
- CentOS/RHEL:
- 重启后执行
cat /proc/cmdline确认参数存在
2. 配置dracut启用开机阶段memstrack收集
- 进入dracut的memstrack模块目录:
cd /usr/lib/dracut/modules.d/90memstrack - 编辑
module-setup.sh,在install函数中添加开机执行逻辑,示例:
install() { inst_multiple memstrack inst_hook pre-mount 00 "${moddir}/memstrack-start.sh" inst_hook mount 99 "${moddir}/memstrack-save.sh" }
- 创建
memstrack-start.sh:
#!/bin/sh memstrack --start
- 创建
memstrack-save.sh:
#!/bin/sh memstrack --dump /sysroot/var/log/memstrack-boot.log
- 赋予脚本执行权限:
chmod +x memstrack-start.sh memstrack-save.sh - 重新生成initramfs:
dracut -f
3. 替换cron为systemd开机服务
用systemd oneshot服务替代cron,确保在模块加载完成后立即执行memstrack:
- 创建
/etc/systemd/system/memstrack-boot.service:
[Unit] Description=Record kernel module memory usage at boot After=sysinit.target [Service] Type=oneshot ExecStart=/usr/bin/memstrack --dump /var/log/memstrack-boot.log [Install] WantedBy=multi-user.target
- 启用服务:
systemctl enable memstrack-boot.service
三、memstrack结果不准的原因说明
memstrack统计的是内核特定内存区域(如initramfs阶段的内存),而手动加载卸载模块时统计的是模块全生命周期的内存(包括运行时动态分配的slab、堆内存等),二者统计维度不同导致差异。建议使用smem或eBPF工具获取更贴近真实场景的内存数据。
内容的提问来源于stack exchange,提问作者amkgi
相关产品推荐
相关产品推荐

