Solaris 11内存占用异常求助:已用超4GB但进程RSS总和不符
这种「进程总RSS远小于系统已用内存」的情况我碰过好几次,大概率是系统层面的内存消耗没被进程统计到,结合你提到的有活跃但未运行的Zone,给你梳理几个重点排查方向:
先看内核层面的内存占用:进程RSS只统计用户态内存,内核本身会吃掉不少内存(比如slab缓存、页表、内核栈这些)。直接跑
cat /proc/meminfo看详细分布,重点盯这几个字段:Slab:内核用来缓存文件元数据、inode的内存,有时候会占很大空间PageTables:所有进程的页表占用的内存,进程多的时候这个数值会很高VmallocUsed:内核动态分配的内存,比如驱动模块用的KernelStack:每个进程都有自己的内核栈,进程数多了累加起来也不少
区分缓存与实际占用的内存:很多人会把
buff/cache当成“已用内存”,但大部分缓存是可以释放的。先跑free -h确认内存结构,如果cached占比很高,试试用echo 3 > /proc/sys/vm/drop_caches(需要root权限)手动释放缓存,要是空闲内存回升了,说明就是缓存占的;要是没变化,再往深了查。排查活跃未运行Zone的内存情况:你提到有活跃但未运行的Zone,Zone是内核划分的内存管理区域(比如DMA、Normal、HighMem)。跑
cat /proc/zoneinfo看各个Zone的细节,重点看free、active、inactive、reserved这些字段,说不定这个Zone里有大量预留内存或者被内核映射的内存没被统计到进程RSS里。检查隐藏的内存消耗项:还有些特殊内存不会被进程RSS统计:
- 共享内存:用
ipcs -m查看,比如数据库、集群工具常用的共享内存段,属于系统内存但不算单个进程的RSS - 匿名映射内存:有些进程用mmap分配的匿名内存,可能没被正确统计,或者僵尸进程遗留的内存
- 内核内存泄漏:用
slabtop实时看slab缓存的变化,如果某个slab对象持续增长,大概率是内核模块或者驱动泄漏了内存
- 共享内存:用
验证总内存差值:用这个命令统计所有进程RSS总和:
ps aux --sort=-%mem | awk '{sum+=$6} END {print sum/1024 " MB"}',然后和free -h里的used内存对比,差值就是系统/内核占用的内存。差值大的话,就盯着内核层面排查准没错。
另外推荐用htop代替top,它会显示缓存、内核内存这些细节,比top直观多了,能更快定位问题。
内容的提问来源于stack exchange,提问作者elbarna

