【发布时间】:2010-10-20 22:44:03
【问题描述】:
是否有工具可以运行命令行并报告 RAM 使用总量峰值?
我在想象类似于 /usr/bin/time 的东西
【问题讨论】:
标签: linux command-line memory-management
是否有工具可以运行命令行并报告 RAM 使用总量峰值?
我在想象类似于 /usr/bin/time 的东西
【问题讨论】:
标签: linux command-line memory-management
您可以使用Valgrind 之类的工具来执行此操作。
【讨论】:
[编辑:适用于 Ubuntu 14.04:/usr/bin/time -v command 确保使用完整路径。]
看起来/usr/bin/time 确实为您提供了该信息,如果您通过-v(这是在 Ubuntu 8.10 上)。参见下面的Maximum resident set size:
【讨论】:
/bin/time -v 解决了。
time -l,得到类似的输出。
/usr/bin/time 实际上可能会做你想做的事。类似的东西。
/usr/bin/time --format='(%Xtext+%Ddata %Mmax)'详见时间(1)...
【讨论】:
也许 (gnu) time(1) 已经做了你想做的事。例如:
$ /usr/bin/time -f "%P %M" command
43% 821248
但其他分析工具可能会根据您要查找的内容提供更准确的结果。
【讨论】:
time 是使用 csh 时的内置命令。如果您使用确切的路径,它将允许您运行外部命令。据我所知,只有 GNU 版本支持 format 选项。
如果进程运行了至少几秒钟,那么您可以使用以下 bash 脚本,该脚本将运行给定的命令行,然后将峰值 RSS 打印到标准错误(替代 rss 任何其他您感兴趣的属性在)。它有点轻巧,它适用于 Ubuntu 9.04 中包含的 ps(我不能说 time)。
#!/usr/bin/env bash
"$@" & # Run the given command line in the background.
pid=$! peak=0
while true; do
sleep 1
sample="$(ps -o rss= $pid 2> /dev/null)" || break
let peak='sample > peak ? sample : peak'
done
echo "Peak: $peak" 1>&2
【讨论】:
cgroupv2,则只有 root 可以创建内存 cgroup。任何基于采样/轮询的 hack 都会错过峰值。(这是一个已经回答的老问题..但只是为了记录:)
我受到杨的剧本的启发,想出了这个小工具,命名为memusg。我只是将采样率提高到 0.1 来处理很短的生命过程。我没有监控单个进程,而是让它测量进程组的 rss 总和。 (是的,我编写了许多可以协同工作的单独程序)它目前可以在 Mac OS X 和 Linux 上运行。用法必须与time类似:
它只显示了目前的峰值,但我对记录其他(粗略)统计数据的轻微扩展感兴趣。
在我们开始任何认真的分析之前,有这样一个简单的工具来看看是件好事。
【讨论】:
ps -o rss= 显示的值,其中 rss 是 进程的实际内存(驻留集)大小(以 1024 字节为单位)。
这是(基于其他答案)一个非常简单的脚本,用于监视已经运行的进程。您只需使用要监视的进程的 pid 作为参数运行它:
#!/usr/bin/env bash
pid=$1
while ps $pid >/dev/null
do
ps -o vsz= ${pid}
sleep 1
done | sort -n | tail -n1
示例用法:
max_mem_usage.sh 23423
【讨论】:
Valgrind 单线:
valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out ./test.sh; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1
注意使用 --pages-as-heap 来测量进程中的所有内存。更多信息在这里:http://valgrind.org/docs/manual/ms-manual.html
这会显着减慢您的命令速度。
【讨论】:
--pages-as-heap 选项。 --trace-children 也可能是 valgrind 的有用选项。我不确定它的作用,但我猜它也会跟踪子进程。
valgrind --massif。您还可以使用它附带的ms_print 工具进行方便的输出(包括随时间变化的 ascii 图表)
time 高得多,在像 ls 这样的命令上花费至少 10 倍以上的时间。
在 MacOS Sierra 上使用:
/usr/bin/time -l commandToMeasure
你可以使用grep来获取你想要的东西。
【讨论】:
command time -l 而不是/usr/bin/time -l,这将导致您的shell 实际上调用一个名为time 的二进制文件而不是内置函数。 (是的,command 不是占位符,command time 与 time 不同。)
'htop' 是查看哪个进程正在使用多少 RAM 的最佳命令.....
了解更多详情 http://manpages.ubuntu.com/manpages/precise/man1/htop.1.html
【讨论】:
Heaptrack 是具有 GUI 和文本界面的 KDE 工具。我发现它比 valgrind 更适合理解进程的内存使用情况,因为它提供了更多细节和火焰图。它也更快,因为它对 valgrind 的检查更少。它还为您提供了峰值内存使用率。
无论如何,跟踪 rss 和 vss 具有误导性,因为页面可以共享,这就是 memusg 的原因。您真正应该做的是在/proc/[pid]/smaps 中跟踪Pss 的总和或使用pmap。 GNOME system-monitor曾经这样做过,但是太贵了。
【讨论】:
使用手工制作的 bash 脚本重新发明轮子。又快又干净。
我的用例:我想监控一台 RAM 较少的 linux 机器,并希望在它在高负载下运行时为每个容器的使用情况拍摄快照。
#!/usr/bin/env bash
threshold=$1
echo "$(date '+%Y-%m-%d %H:%M:%S'): Running free memory monitor with threshold $threshold%.."
while(true)
freePercent=`free -m | grep Mem: | awk '{print ($7/$2)*100}'`
do
if (( $(awk 'BEGIN {print ("'$freePercent'" < "'$threshold'")}') ))
then
echo "$(date '+%Y-%m-%d %H:%M:%S'): Free memory $freePercent% is less than $threshold%"
free -m
docker stats --no-stream
sleep 60
echo ""
else
echo "$(date '+%Y-%m-%d %H:%M:%S'): Sufficient free memory available: $freePercent%"
fi
sleep 30
done
样本输出:
2017-10-12 13:29:33:以 30% 的阈值运行空闲内存监视器..
2017-10-12 13:29:33:可用内存充足:69.4567%
2017-10-12 13:30:03:可用内存充足:69.4567%
2017-10-12 16:47:02:可用内存 18.9387% 小于 30%
您的自定义命令输出
【讨论】:
在 Linux 上:
使用/usr/bin/time -v <program> <args> 并查找“Maximum resident set size”。
(不要与 Bash time 内置命令混淆!所以使用完整路径,/usr/bin/time)
例如:
> /usr/bin/time -v ./myapp
User time (seconds): 0.00
. . .
Maximum resident set size (kbytes): 2792
. . .
在 BSD、MacOS 上:
使用/usr/bin/time -l <program> <args>,寻找“最大驻留集大小”:
>/usr/bin/time -l ./myapp
0.01 real 0.00 user 0.00 sys
1440 maximum resident set size
. . .
【讨论】:
sudo apt-get install time
在 macOS 上,您可以改用 DTrace。 “Instruments”应用程序是一个很好的 GUI,它带有 XCode afaik。
【讨论】:
time -f '%M' <run_program>
【讨论】:
/usr/bin/time,为了不使用不支持-f的内置time关键字。
请务必回答问题。提供详细信息并分享您的研究!
对不起,我是第一次来,只能问问题……
使用建议:
valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out ./test.sh; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1
然后:
grep mem_heap_B massif.out
...
mem_heap_B=1150976
mem_heap_B=1150976
...
这与top 命令在类似时刻显示的非常不同:
14673 gu27mox 20 0 3280404 468380 19176 R 100.0 2.9 6:08.84 pwanew_3pic_com
Valgrind 的测量单位是什么??
/usr/bin/time -v ./test.sh 从未回答 — 您必须直接将可执行文件提供给 /usr/bin/time,例如:
/usr/bin/time -v pwanew_3pic_compass_2008florian3_dfunc.static card_0.100-0.141_31212_resubmit1.dat_1.140_1.180 1.140 1.180 31212
Command being timed: "pwanew_3pic_compass_2008florian3_dfunc.static card_0.100-0.141_31212_resubmit1.dat_1.140_1.180 1.140 1.180 31212"
User time (seconds): 1468.44
System time (seconds): 7.37
Percent of CPU this job got: 99%
Elapsed (wall clock) time (h:mm:ss or m:ss): 24:37.14
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 574844
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 74
Minor (reclaiming a frame) page faults: 468880
Voluntary context switches: 1190
Involuntary context switches: 20534
Swaps: 0
File system inputs: 81128
File system outputs: 1264
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
【讨论】:
这是一个单行程序,不需要任何外部脚本或实用程序,也不需要您通过 Valgrind 或 time 等其他程序启动进程,因此您可以将其用于任何已经运行的进程:
grep ^VmPeak /proc/$PID/status
(将$PID替换为您感兴趣的进程的PID)
【讨论】:
VmPeak 应该没什么大不了的。是VmHWM 导致系统内存不足。在用完实际 RAM 之前,在 64 位操作系统上用完虚拟内存是闻所未闻的。
因为/usr/bin/time 在许多现代发行版中不存在(取而代之的是 Bash 内置时间),您可以使用带有 -v 参数的 Busybox 时间实现:
busybox time -v uname -r
它的输出类似于 GNU 时间输出。 Busybox 预装在大多数 Linux 发行版(Debian、Ubuntu 等)中。如果你使用 Arch Linux,你可以安装它:
sudo pacman -S busybox
【讨论】: