有没有办法记录 Linux 中每个进程使用的内存量?我们的一台服务器的内存使用量有时会激增,导致机器停机,记录确实可以帮助我们找到根本原因。
答案1
如果您的需求不是很复杂,也许您可以使用ps
while 循环:
while true; do date; ps auxw --sort rss | tail -n 10; echo; sleep 60; done >> logfile
这将每分钟记录前十个进程(按内存使用情况)。
答案2
最干净的解决方案是放入一个 cron 作业,它执行类似以下操作
ps auxww | logger -p local0.info -t ps
这会将ps
输出通过日志守护进程记录到 local0 设备(可以更改为任何您想要的)
答案3
以下是关于如何诊断导致内存峰值的几个建议鞭笞在服务器上,使用我编写的 Linux 进程分析工具,进程路径。
最明显的临时诊断是记录所有进程的指标,并在问题再次发生时查看记录。例如,可以在终端多路复用器中完成此操作,例如屏风(以最少的努力使其在后台运行)。
procpath record -i 60 -d all.sqlite
这将生成一个 SQLite 数据库并记录其中每个进程每分钟的 Procfs 指标。事后您可以查询数据库,例如,查找消耗了 10% 以上可用主内存的 PID(RSS 以页为单位)。
SELECT DISTINCT stat_pid
FROM record
WHERE 1.0 * stat_rss / (SELECT value FROM meta WHERE key = 'physical_pages') > 0.1
并绘制PID的RSS增长图。
procpath plot -d all.sqlite -q rss -p $PID
或者,如果您想要更频繁地获取指标,比如因为峰值很快,并且为了避免最终得到一个很大的 SQLite 数据库,您可以:
仅记录相关的进程子树(例如
$ROOT_PID
及其后代):procpath record -i 10 -d tree.sqlite "$..children[?(@.stat.pid == $ROOT_PID)]"
您可能可以向您的进程管理器(systemd、supervisord 等)询问 PID。
仅记录消耗超过 X MiB(比如 256 MiB,通常相当于 65536 个内存页)的进程:
procpath query '$..children[?(@.stat.rss > 65536 and @.pop\("children", 1\))]'
@.pop("children", 1)
除非匹配进程本身匹配,否则将删除匹配进程的后代。
如果数据库中产生了一些 PID,您可能能够procpath plot
立即对其进行视觉分析。