如何在 Linux 上记录内存消耗?

Posted

技术标签:

【中文标题】如何在 Linux 上记录内存消耗?【英文标题】:How to log the memory consumption on Linux? 【发布时间】:2010-12-24 12:04:39 【问题描述】:

是否有任何现成的解决方案来记录系统启动时的内存消耗?我想将数据记录到简单的文本文件或某个数据库中,以便以后进行分析。

我正在开发基于 Linux 2.4 的嵌入式系统。我需要调试与内存消耗相关的问题。我的应用程序会在每次系统启动时自动启动。我需要定期(尽可能频繁地)获取带有时间戳的数据的方法,这样我就可以追踪问题。

我的问题的症状:当系统启动时,它启动了我的主应用程序和 GUI 以可视化系统的主要参数。基于 GTK+(X 服务器)的 GUI。如果我禁用 GUI 和 X 服务器,那么我的应用程序可以正常工作。如果我启用 GUI 和 X 服务器,当我在主板上安装 256 MiB 或 512 MiB 的物理内存时,它不起作用。如果我安装了 1 GiB 的内存,那么一切正常。

【问题讨论】:

这看起来类似于这个问题:***.com/questions/131303/… 您的应用在崩溃之前是否至少运行了一段时间? 是的,以前的版本在同一个系统中运行正常。现在我们开发新版本,开始解决这个问题。 【参考方案1】:

以下脚本打印时间戳和标题。

#!/bin/bash -e

echo "      date     time $(free -m | grep total | sed -E 's/^    (.*)/\1/g')"
while true; do
    echo "$(date '+%Y-%m-%d %H:%M:%S') $(free -m | grep Mem: | sed 's/Mem://g')"
    sleep 1
done

输出如下所示(在 Ubuntu 15.04,64 位上测试)。

      date     time          total       used       free     shared    buffers     cached
2015-08-01 13:57:27          24002      13283      10718        522        693       2308
2015-08-01 13:57:28          24002      13321      10680        522        693       2308
2015-08-01 13:57:29          24002      13355      10646        522        693       2308
2015-08-01 13:57:30          24002      13353      10648        522        693       2308

【讨论】:

【参考方案2】:

类似的小脚本

rm memory.log
while true; do free >> memory.log; sleep 1; done

【讨论】:

确实,这非常接近我的需要。我可以自己添加时间戳。 free -s 1 > memory.log;这不会产生每秒启动一个新进程的成本。不过,它没有时间戳。 (我知道这是一篇旧帖子,但我一直在寻找同样的东西,其他人也是如此)。 在某些免费版本中,由于存在错误,需要使用 -c 指定要打印的次数。否则它会显示无错误:秒参数 `1' failed 感谢@Sputnik,您还必须指定秒前的计数。例如。 free -h -c 3 -s 1 .@hirschhornsalz - 是否可以读取任何特定的sysfs 然后记录内存使用情况?我正在使用一个用C 编写的程序,并希望以最小的开销使用它进行日志记录?【参考方案3】:

我非常喜欢记录所有内容,我发现了解哪些进程正在使用内存以及每个进程正在使用多少内存(以及汇总统计信息)很有用。以下命令每 0.5 秒记录一次按内存消耗排序的最高打印输出:

top -bd0.5 -o +%MEM > memory.log

请注意,日志文件的增长速度将比仅存储总内存利用率统计信息快得多,因此请确保不会耗尽磁盘空间。

【讨论】:

谢谢,这比免费提供的信息要多得多。【参考方案4】:

有个程序叫

sar

在 *nix 系统上。您可以尝试使用它来监控内存使用情况。它定期进行测量。做一个

man sar

了解更多详情。我认为选项是 -r 进行内存测量,-i 指定您想要的间隔。

【讨论】:

绝对比其他提议的解决方案更强大,虽然设置起来有点麻烦。 例如sar -r 2 5 每两秒报告五次。它还允许您以二进制格式导出和读取输出文件。【参考方案5】:

我认为添加一个 crontab 条目就足够了

*/5 *  *  *  *  free -m >> some_output_file

还有其他工具,例如 SeaLion、New Relic、Server Density 等,它们几乎可以做同样的事情,但更容易安装和配置。我最喜欢的是 SeaLion,因为它是免费的,而且它还提供了一个很棒的时间线视图,可以查看常见 linux 命令的原始输出。

【讨论】:

为海狮+1,这是有史以来最快的注册/设置。我认为整个过程花了我大约 6 秒钟——我输入了我的电子邮件和密码。将一个命令粘贴到 ssh 中,然后我的统计信息就出现了。【参考方案6】:

你可以放一些像

vmstat X >> mylogfile

进入启动脚本。由于您的应用程序已经在启动中,您只需将这一行添加到您的应用程序已经使用的初始化脚本的末尾即可。 (其中 X 是日志消息之间的秒数)

【讨论】:

感谢您的提示,尽管我需要更频繁地记录数据,然后每秒。【参考方案7】:

为了定期有效地记录内存使用情况,我在这里将another answer 与a method 结合起来,只保留前K 个内存使用进程。

top -bd 1.5 -o +%MEM | grep "load average" -A 9 > memory_usage.log

此命令将每 1.5 秒记录一次最高的头信息和 3 个最高内存消耗的进程(top 的头信息有 6 行偏移量)。与为每个进程记录 top 的信息相比,这可以节省大量磁盘空间。

【讨论】:

【参考方案8】:

所以我知道我玩这个游戏迟到了,但我只是想出了这个答案,因为我需要这样做,并且真的不想要 vmstat 的额外字段, free 等...所有的输出似乎都没有过度过滤。所以这是我想出的答案:

top -bd 0.1 | grep 'KiB Mem' | cut -d' ' -f10 > memory.txt

或者:

top -bd 0.1 | grep 'KiB Mem' | cut -d' ' -f10 | tee memory.txt

grep 一起时,来自 top 的标准输出Kib Mem 是:

KiB Mem : 16047368 total,  8708172 free,  6015720 used,  1323476 buff/cache

通过 cut 运行,我们过滤到字面上只是 used

之前的数字

用户确实可以将 0.1 修改为另一个数字,以便运行不同的捕获采样率。在我的情况下,我想使用 top 也是因为您可以在每次捕获时以超过 1 秒的速度运行内存统计信息,正如您在此处看到的那样,我想每次捕获一个统计信息1/10 秒。

注意事项: 事实证明,通过 cut 进行管道传输会导致将任何内容归档的巨大延迟。正如我们后来发现的那样,在数据采集过程中省略 cut 命令要快得多,然后稍后对输出文件执行剪切命令。 此外,我们的测试中不需要时间戳。

因此看起来如下:

开始记录:

top -bd 0.1 | grep 'KiB Mem' | tee memory_raw.txt

退出日志记录:

ctrl-z (to exit logging)

过滤器:

2 级剪切(过滤),首先是逗号,然后是空格。这是由于 top 的对齐并提供了更清晰的输出:

cut memory_raw -d',' -f3 | tee memory_used_withlabel.txt
cut memory_used_withlabel.txt -d' ' -f3 | tee memory_used.txt

【讨论】:

以上是关于如何在 Linux 上记录内存消耗?的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在java中的堆上单独获取所有对象消耗的运行时内存

Linux 查看进程消耗内存情况总结

查看占用内存最多的进程

Linux运维工程师必知:如何根据内存使用情况对 top 命令进行排序?

如何跟踪android应用程序消耗的峰值内存

Linux 有问必答:如何知道进程运行在哪个 CPU 内核上?