内存泄漏与缓存淤积是系统长期运行后性能缓慢退化的主因,表现为available持续下降、slab异常增长、rss爬升及文件句柄或inode耗尽,需结合free、/proc/meminfo、ps、lsof和dmesg等工具综合排查。

系统长时间运行后性能逐渐退化,不是突发故障,而是缓慢积累的结果。这类问题往往不触发明显告警,但用户会感知到响应变慢、延迟升高、服务偶发超时——根源通常藏在资源泄漏、缓存失衡或内核状态老化中。
查内存泄漏与缓存淤积
长期运行下,内存泄漏(尤其是Java、Node.js等进程)或内核缓存未及时回收,会导致可用内存持续下降,进而频繁触发swap或OOM Killer。
- 用 free -h 观察 available 值是否逐日减少,同时 buff/cache 持续上涨;
- 对比 cat /proc/meminfo 中的 Slab、SReclaimable 和 PageTables,若 Slab 长期增长且 SReclaimable 占比低,说明内核对象(如dentry、inode)未有效回收;
- 检查是否有进程 RSS 持续爬升:用 ps aux --sort=-%mem | head -10 定期快照比对,重点关注常驻进程;
- 避免随意执行 echo 3 > /proc/sys/vm/drop_caches —— 它只清缓存,不解决泄漏,还可能加剧IO压力。
盯住文件句柄与inode耗尽
服务长期不重启,容易因未关闭文件描述符或删除后未释放的文件(deleted but held),导致句柄数或inode耗尽,表现为“Too many open files”或磁盘空间明明充足却报“No space left on device”。
- 用 lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 查看哪些PID打开的文件最多;
- 用 lsof +L1 直接列出已删除但仍被占用的文件(deleted 状态);
- 用 df -i 检查 inode 使用率,尤其关注 /var/log、/tmp 等高频写入目录;
- 确认应用是否正确调用
close()或使用连接池,Java 应用需检查try-with-resources或连接泄漏。
观察内核状态老化与中断堆积
某些驱动、网卡或存储子系统在高负载长周期运行后,可能出现中断处理延迟、软中断(si)占比异常升高、或 dmesg 中持续出现 warning/err,例如 time jump、GRO misbehavior、nvme timeout 等。
- 运行 dmesg -T | tail -50,重点搜 error、warning、timeout、stuck、hung;
- 用 vmstat 1 10 看 si(swap in)、so(swap out)、cs(上下文切换)、in(中断次数)是否随时间缓慢上升;
- 用 cat /proc/interrupts 检查某 CPU 上特定中断(如 eth0、nvme)计数是否远高于其他 CPU,暗示中断绑定失衡;
- 对虚拟机环境,还需关注宿主机 steal time(st 列)是否持续偏高,表明底层资源争抢严重。
跟踪进程行为漂移与调度退化
有些进程随运行时间推移,线程数激增、堆栈深度变大、或陷入不可中断睡眠(D 状态),导致调度器负担加重、CPU 时间片分配失衡。
- 用 ps -eo pid,ppid,comm,wchan:20,state,etime | awk '$6 > 86400' | grep ' D ' 找出运行超24小时且处于 D 状态的进程;
- 用 ps -eLf | awk '{print $2}' | sort | uniq -c | sort -nr | head -5 统计线程数最多的 PID,再结合 ls /proc/
/task/ | wc -l 验证; - 对 Java 进程,定期抓取 jstack
对比线程状态变化,看是否有线程池无限扩容或锁等待链延长; - 检查 /proc/
/status 中的 voluntary_ctxt_switches 与 nonvoluntary_ctxt_switches 比值,若后者占比突增,说明频繁被抢占或阻塞。











