Unix 命令告诉程序运行时使用了多少 RAM?

Sha*_*ang 44 memory command ram

假设我正在运行一个脚本(例如在 Python 中)。为了找出程序花费了多长时间,可以运行

time python script1.py
Run Code Online (Sandbox Code Playgroud)

是否有一个命令可以跟踪脚本运行时使用了多少 RAM?为了找到有多少 RAM 可用,可以使用free,但此命令不适合上述任务。

Bas*_*tch 60

时间(1)命令(您可能需要安装它-perhaps作为time套餐的,应该在/usr/bin/time)接受许多参数,包括格式字符串(带-f--format)其理解(其中包括)

  %M     Maximum resident set size of the process during its lifetime,
          in Kbytes.

  %K     Average total (data+stack+text) memory use of the process, in
          Kbytes.
Run Code Online (Sandbox Code Playgroud)

不要将/usr/bin/time命令与time 内置bash混淆。您可能需要输入完整的文件路径/usr/bin/time(要求您的 shell 运行命令而不是内置命令)或输入command time\time(感谢Toby Speight & to Arrow的评论)。

所以你可以试试(RSS 是常驻集大小

/usr/bin/time -f "mem=%K RSS=%M elapsed=%E cpu.sys=%S .user=%U" python script1.py
Run Code Online (Sandbox Code Playgroud)

你也可以试试

/usr/bin/time --verbose  python script1.py
Run Code Online (Sandbox Code Playgroud)

你在问:

脚本运行时使用了多少内存?

这表明您存在误解。在 Linux(或任何现代多进程操作系统)上运行的应用程序使用虚拟内存,每个进程(包括python运行脚本的进程)都有自己的虚拟地址空间进程不直接物理RAM 中运行,但有自己的虚拟地址空间(并在其中运行),内核通过使用延迟写入时复制技术的复杂需求分页来实现虚拟内存,并配置MMU。该RAM是用于-and管理的物理设备和资源内部由内核实现虚拟内存(另请阅读有关页面缓存抖动的信息)。

您可能想花几天时间了解更多有关操作系统的信息。我建议阅读操作系统:三部曲,这是一本可免费下载的书。RAM 由整个操作系统使用(而不是直接由单个进程使用),并且给定进程的 RAM 中的实际页面可能会随时间变化(并且可能以某种方式与其他进程共享)。因此,给定进程的 RAM 消耗没有很好地定义,因为它在不断变化(您可能想要它的平均值,或它的峰值,等等),同样对于它的虚拟地址空间的大小。

您还可以使用(特别是如果您的脚本运行了几秒钟)top(1)实用程序(可能在其他一些终端中),或ps(1)pmap(1) -也许使用watch(1)重复该pspmap命令. 你甚至可以直接使用/proc/(见PROC(5)或许......)作为watch cat /proc/$(pidof python)/status/proc/$(pidof python)/stat/proc/$(pidof python)/maps等...

但是RAM使用(由内核对于一些过程)广泛地随时间变化对于给定的处理(甚至它的虚拟地址空间是变化的,例如通过调用MMAP(2)munmap由用于LD-Linux的(8) 执行dlopen( 3)malloc(3) &free以及 Python 解释器所需的许多其他函数......)。

您还可以使用strace(1)来了解Python 为您的脚本执行的系统调用(以便您了解它如何使用mmap&munmap和其他syscalls(2))。您可能会限制或仅获取strace与内存(即虚拟地址空间)相关的系统调用。-e trace=%memory-e trace=memory

顺便说一句,tracemalloc Python 功能也很有用。

我猜关心 virtual memory,即虚拟地址空间(而不是 RAM),Python 解释器使用它来运行您的 Python 脚本。这在流程执行期间正在发生变化。RSS(或虚拟地址空间的最大峰值大小)实际上可能更有用。

另见LinuxAteMyRAM

  • 如果您在无法区分概念和术语时更喜欢变得个人化,那么我对您的讨论风格不感兴趣。 (7认同)
  • 您不需要完整路径 - `command time` 会告诉 Bash 忽略内置。如果你不记得哪个 `bin` 目录保存它,这很有用。 (4认同)
  • @TobySpeight 或者更简单:`\time` 会告诉 shell 在 PATH 中搜索。反斜杠与时间内置名称不完全匹配,因此将在 PATH 中启动搜索。 (4认同)
  • 你希望我花几天时间读一本书,我可能已经知道了 99% 来找到一个术语的解释?一个简单的“是”或“现在”可以为我节省很多时间。)-: (2认同)
  • 但是 RSS 的概念(与虚拟内存相关)并不容易解释。也许维基页面对你来说就足够了。我的观点是,您的幼稚问题(python 脚本花费了多少 RAM)没有*精确* 的含义,因为进程不使用 RAM(而是使用虚拟地址空间,*不相同*)。究竟发生了什么,确实至少需要一整本书(也许更多)来解释。 (2认同)

cat*_*cat 18

您也可以使用传奇的valgrind,尽管您可能需要从包管理器中安装它。

$ valgrind c-projects/objtest/bin/objtest 
==6543== Memcheck, a memory error detector
==6543== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6543== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==6543== Command: c-projects/objtest/bin/objtest
==6543== 
|ERROR|array:189: array_delete: delete index 0 but the highest is -1 (delete from empty array): index out of bounds
==6543== 
==6543== HEAP SUMMARY:
==6543==     in use at exit: 480 bytes in 20 blocks
==6543==   total heap usage: 7,390 allocs, 7,370 frees, 256,217 bytes allocated
==6543== 
==6543== LEAK SUMMARY:
==6543==    definitely lost: 96 bytes in 4 blocks
==6543==    indirectly lost: 384 bytes in 16 blocks
==6543==      possibly lost: 0 bytes in 0 blocks
==6543==    still reachable: 0 bytes in 0 blocks
==6543==         suppressed: 0 bytes in 0 blocks
==6543== Rerun with --leak-check=full to see details of leaked memory
==6543== 
==6543== For counts of detected and suppressed errors, rerun with: -v
==6543== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

如果您是高级用户并且想要精美的图表,您可以使用如下ms_print命令:

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
Run Code Online (Sandbox Code Playgroud)

请参阅linux/unix 进程的峰值内存使用情况

  • 这是一个很好的建议 - 可能值得指出的是,您无法区分长期分配的大量内存和许多较小的短期分配之间的区别。很难知道提问者是否也对其他内存使用(堆栈、映射文件、文本段等)感兴趣。 (2认同)