如何在 OSX 上获得内存使用率高水位线

Lin*_*ler 5 macos bash dtrace

我希望能够测试对各种命令行实用程序的内存复杂性的一些猜测。

举个简单的例子

grep pattern file
Run Code Online (Sandbox Code Playgroud)

我想看看内存使用如何随 的大小patternfile.

对于时间复杂度,我会猜测,然后运行

time grep pattern file
Run Code Online (Sandbox Code Playgroud)

在各种大小的输入上,看看我的猜测是否在现实中得到证实,但我不知道如何为记忆做到这一点。

一种可能性是使用包装脚本启动作业并定期对内存使用情况进行采样,但这似乎不雅,不太可能给出真正的高水印。

我已经看到了time -v建议,但我的机器上没有该标志(在 OSX 上运行 bash)并且不知道在哪里可以找到支持它的版本。

我还看到,在 Linux 上,此信息可通过proc文件系统获得,但同样,在我的上下文中无法获得。

我想知道是否dtrace可能是一个合适的工具,但再次担心一个简单的基于样本的数字可能不是真正的高水印?

有谁知道适合 OSX 的工具或方法吗?

编辑

我删除了两次提到的磁盘使用情况,这只是旁白,可能会分散问题的主旨。

Rob*_*ris 6

您的问题很有趣,因为如果没有应用程序源代码,您需要对内存使用的构成进行一些假设。即使您使用procfs,结果也会产生误导:驻留集大小和总虚拟地址空间都将被高估,因为它们将包括无关数据,例如程序文本。

特别是对于小命令,跟踪单个分配会更容易,尽管即使在那里您也需要确保包含所有可能的来源。除了malloc()etc 之外,进程还可以使用 扩展其堆brk()或获取匿名内存mmap()

这是一个跟踪 DTrace 的脚本malloc();您可以扩展它以包含其他分配函数。请注意,它不适合多线程程序,因为它使用了一些非原子变量。

bash-3.2# cat hwm.d
/* find the maximum outstanding allocation provided by malloc() */
size_t total, high;

pid$target::malloc:entry
{
    self->size = arg0;
}

pid$target::malloc:return
/arg1/
{
    total += self->size;
    allocation[arg1] = self->size;
    high = (total > high) ? total : high;
}

pid$target::free:entry
/allocation[arg0]/
{
    total -= allocation[arg0];
    allocation[arg0] = 0;
}

END
{
    printf("High water mark was %d bytes.\n", high);
}
bash-3.2# dtrace -x evaltime=exec -qs hwm.d -c 'grep maximum hwm.d'
/* find the maximum outstanding allocation provided by malloc() */
High water mark was 62485 bytes.

bash-3.2#
Run Code Online (Sandbox Code Playgroud)

Brendan Gregg 的这篇文章中包含了对内存分配器的更全面的讨论。它为您的问题提供了比我自己更好的答案。特别是,它包含一个指向名为memleak.d;的脚本的链接。修改它以包含分配和释放的时间戳,以便您可以按时间对其输出进行排序。然后,也许使用随附的脚本作为示例,用于perl跟踪当前未完成的总分配和高水位标记。这样的dtrace / perl的组合是适合于跟踪的多线程处理。