我遇到崩溃(每天大约 0.5 次)。内存使用率从大约 40% 上升到 100%,一两秒内没有任何启动,并且机器冻结。我没有时间反应。没有使用交换。我想查看日志以了解导致此问题的原因,但我不确定在哪里可以找到隔离进程的内存使用日志。
答案1
这是我几年前做的事情,目的是收集一些内存使用量快速增长的服务器上的数据。我的服务器在很短的几分钟内完成了这项工作,因此该技术能够捕获数据。如果您的内存使用量在短短几秒钟内出现峰值,它可能对您没有那么有用。
我使用top
批处理模式,每 15 秒根据内存使用情况将前 30 个进程写入文件。在内存峰值事件发生后,该文件向我显示了哪些进程的内存使用量出现了增长,以及它们的增长速度大致如下:
LINES=30 COLUMNS=160 top -b -c -o RES -d 15 -n 40 -w >> /path/to/output.txt
选项:
top
关于它如何处理它报告的进程数量以及它显示的每个进程的命令行数量,有一些怪癖。COLUMNS
和变量ROWS
是其中的一部分,我用-w
最后的选项解释它们:
-b
选择批处理模式,其中行的摘要块和每个进程的行的输出不突出显示,也不分页,因此它们将正确附加到输出文件。-c
切换每个进程行中命令的显示。通常top
配置为显示unattended-upgrades
每个进程的基本命令(如 ),并将-c
更改为显示带有参数的完整命令行(如/usr/bin/python3 /usr/share/unattended-upgrades/...
)。如果您像我一样在服务器上有两个或三个 java 进程,并且需要知道其中哪个进程出现内存峰值,那么这会很有用。-o RES
根据内存使用情况从最大到最小对每个进程的行进行排序。内存以 KiB 为单位。另一种方法是以-o %MEM
总内存的百分比形式给出内存使用情况。-d 15
每次检查进程(以及输出线突发)之间延迟 15 秒。这意味着top
每分钟检查四次。-n 40
选择 40 个样本,然后top
命令退出。总共 40 个样本(每分钟 4 个)意味着最高运行 10 分钟然后退出。-w
为每个进程选择“宽”(长)行,因此命令参数不会被截断。-w
可以接受指定列的参数,但是当我这样做时,top
会写一行全部进程而不仅仅是前 30 个进程。保持命令-w
的简洁性并在命令前加上前缀top
使得LINES=30 COLUMNS=160
top 显示宽行并且仅显示内存使用率最高的 30 个进程。手册页建议在设置和变量-w
时不需要该选项,但似乎忽略并输出所有进程。该选项放在最后,因为如果在其后有其他选项,top 会抱怨参数无效。根据需要调整和值,以及和数字。LINES
COLUMNS
top
LINES
-w
LINES
COLUMNS
-d
-n
其他可能有用的选项:
-E
更改摘要行中的内存比例。-E m
选择MiB,然后-E g
选择GiB。不过,只有摘要行,而不是每个进程的行。-u username
将每个进程行限制为以用户身份运行的行username
-p pid,pid
将每个进程行限制为列表中的进程 ID。
手册top
页提供了有关上述选项的更多信息,包括该-o
选项的其他字段名称(运行top -O
以查看字段名称的快速列表)。
我使用该 top 命令编写了一个脚本,并且每 10 分钟从 cron 调用该脚本一次。我不必编写一个 shell 脚本来充当长时间运行的后台进程,但我仍然获得了已在运行的进程在内存峰值发生时捕获它们的优势。
输出文件不容易被软件解析,因为每个样本都有一个包含摘要信息的行块、一两行空行以及 30 行进程。但当时手动检查该文件对我来说就足够了。一个小小的胜利:摘要行有一个内置时间戳,对于在峰值事件发生前不久查找文件部分非常有用。
很可能还有其他方法来捕获 Linux 计算机上各个进程的内存消耗,并且它们可能比这种方法更好。我只是传递一种对我有用的方法。希望它对您也有用。