如何使用 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 脚本将为您提供最大内存利用率的上限,因为您不跟踪 free
s 以及 malloc
s。你可能不在乎这个。如果您确实关心,因为free
不接受或返回释放范围的大小,您最好跟踪brk()
系统调用返回值,这也说明了malloc
的所有元数据的大小在堆上存储。对此的替代方法(如果您想要确切的答案)是弄清楚 malloc
和 free
的数据结构如何为您的操作系统工作,并在 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 进行挂钟分析?或者,如何使用配置文件提供程序计算进程未运行的样本?
如何编写 dtrace 脚本来转储 Solaris 10 上崩溃进程的堆栈?