The following dtrace script will give the sum of all allocations a process has performed:

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

Now, I'm rather interested in the maximum total allocated memory usage during the life-span of the process (about 50 ms). How can I generate either what would be a graph over time of total allocated memory usage (sum of all mallocs minus sum of all frees), or just its maximum value. I've tried keeping track of all allocated memory blocks manually, but the dtrace associative array size limit is exceeded.

有帮助吗?

解决方案

First, your dtrace script will give you an upper bound on the maximum memory utilization since you don't track frees as well as mallocs. You might not care about this. If you do care, since free doesn't take in or return the size of the freed range, you might be better off tracing the brk() syscall return value, which also accounts for the size of all metadata that malloc stores on the heap. The alternative to this (if you want exact answers) is to figure out how the data structures for malloc and free work for your OS and dig into some pointer arithmetic in DTrace to get that info.

Second, a word of caution - if you're using this to implement a very fast allocator, keep in mind that you need the size of the entire heap (not just the memory that malloc returns), since alignment of values stored in memory is important and the ranges returned by malloc don't include this "dead space".

Now, on to your question.

  1. You can get a picture over time by tracing the data as it comes in. Just use printa(@) to print the current value of the aggregation after every time you call @ = sum(...).

  2. Alternately, if you want a more accurate time axis in the picture this would generate, you could record the timestamp with the malloc size, like @[walltimestamp] = sum(...). In that case, each entry in the aggregation would only include a single allocation size rather than the sum of all aggregations so far.

  3. If you like the first solution better but also want an accurate time axis, just trace(walltimestamp) before your call to printa(@) in the first example.

If you're not set on using DTrace, you can always use /usr/bin/time -lp (on Mac OS X - for other platforms the same thing exists but the arguments are different) to get some static information about process resource utilization.

% /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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top