如何使用 dtrace 确定进程的最大内存使用量

Posted

技术标签:

【中文标题】如何使用 dtrace 确定进程的最大内存使用量【英文标题】:How to use dtrace to determine the maximum memory usage of a process 【发布时间】:2013-04-03 10:57:18 【问题描述】:

以下 dtrace 脚本将给出进程已执行的所有分配的总和:

pid$target::malloc:entry  @ = sum(arg0); 

现在,我对进程生命周期内的最大总分配内存使用量(大约 50 毫秒)很感兴趣。如何生成总分配内存使用量的图表(所有 malloc 的总和减去所有空闲的总和),或者只是它的最大值。我尝试手动跟踪所有分配的内存块,但超出了 dtrace 关联数组大小限制。

【问题讨论】:

【参考方案1】:

首先,您的 dtrace 脚本将为您提供最大内存利用率的上限,因为您不跟踪 frees 以及 mallocs。你可能不在乎这个。如果您确实关心,因为free 不接受或返回释放范围的大小,您最好跟踪brk() 系统调用返回值,这也说明了malloc 的所有元数据的大小在堆上存储。对此的替代方法(如果您想要确切的答案)是弄清楚 mallocfree 的数据结构如何为您的操作系统工作,并在 DTrace 中挖掘一些指针算法以获取该信息。

其次,请注意 - 如果您使用它来实现一个非常快速的分配器,请记住您需要 整个 堆的大小(不仅仅是@987654330 的内存@return),因为存储在内存中的值的对齐很重要,而且 malloc 返回的范围不包括这个“死区”。

现在,回答你的问题。

    您可以通过跟踪传入的数据来获得一张随时间变化的图片。每次调用@ = sum(...) 后,只需使用printa(@) 打印聚合的当前值。

    李>

    或者,如果您想要在图片中生成更准确的时间轴,您可以使用malloc 大小记录时间戳,例如@[walltimestamp] = sum(...)。在这种情况下,聚合中的每个条目将只包含一个分配大小,而不是到目前为止所有聚合的总和。

    如果您更喜欢第一个解决方案,但又想要一个准确的时间轴,只需在第一个示例中调用printa(@) 之前trace(walltimestamp)

如果您不打算使用 DTrace,您始终可以使用/usr/bin/time -lp(在 Mac OS X 上 - 对于其他平台存在相同的情况,但参数不同)来获取有关进程资源利用率的一些静态信息。

% /usr/bin/time -lp 'date'
Tue Jun 25 14:14:35 PDT 2013
real         0.00
user         0.00
sys          0.00
    561152  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
       158  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         0  block output operations
         0  messages sent
         0  messages received
         0  signals received
         0  voluntary context switches
     3  involuntary context switches

【讨论】:

感谢您的回答。我对最大内存利用率感兴趣(不仅仅是上限,因为这太高了几个数量级)。我尝试跟踪brk(),但在我的操作系统(OSX)上malloc() 似乎使用mmap()。我未能从追踪mmap()/munmap() 中获得合理的总价值。跟踪当前驻留内存页的数量是理想的,但我不知道该怎么做。 在你的进程上运行/usr/bin/time -lp怎么样?我学会了这个技巧from another question,它似乎在 Mac OS X 上运行得很好。仅供参考,DTrace 中也有 vminfo provider,尽管它很难用于测量进程的最大大小。 谢谢。 /usr/bin/time -lp 给了我想要的。

以上是关于如何使用 dtrace 确定进程的最大内存使用量的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 dtrace 显示每个进程消耗的微秒 cpu?

如何使用 dtrace 进行挂钟分析?或者,如何使用配置文件提供程序计算进程未运行的样本?

dtrace 将在将来运行的用户进程

如何编写 dtrace 脚本来转储 Solaris 10 上崩溃进程的堆栈?

如何使用 Dtrace 在 Solaris 10 上检查 malloc?

如何用 D 语言正确打印 uint64_t (dtrace)