Search code examples
debuggingoptimizationfortranvalgrindheap-memory

How to track lifetime heap usage from repeated allocations


I have a program that is using a lot more memory total over its lifetime than I am expecting and I'd like to see if there's anything I can do about it.

I've used Valgrind's memcheck tool to get rid of the memory leaks, and Valgrind's massif tool to see heap snapshots. massif can tell me which lines are responsible for the largest heap blocks at a particular point in time. Since massif doesn't show anything very large, I suspect my problem is particular lines that do smaller allocations lots of times.

In case some numbers would be helpful: the program runs for about 5s, doing intensive numerical calculations. The peak memory usage is 1MB. The lifetime memory usage is 10GB. The largest single allocation is 250KB and that is done 8 times.

Therefore what I wish to see is not which lines have allocated a lot of memory at any particular point in time, but a sum over the whole lifetime of the program for each line that allocates. I feel that Valgrind should have access to that information, since it's tracking every allocation, but I don't know how to get it to tell me.

Can any one suggest either how to use Valgrind to report this information, or another tool that will do what I want?


Solution

  • As I understand, you do not want to look at the 'snapshot' of current memory usage, but you want to look at the cumulative allocations done by a stack trace, even if most of the allocated memory was released.

    For this, you might try the option --xtree-memory=full.

    The xtrees produced by the option --xtree-memory or the xtmemory monitor command are showing the following events/resource consumption describing heap usage:
    
        curB current number of Bytes allocated. The number of allocated bytes is added to the curB value of a stack trace for each allocation. It is decreased when a block allocated by this stack trace is released (by another "freeing" stack trace)
    
        curBk current number of Blocks allocated, maintained similary to curB : +1 for each allocation, -1 when the block is freed.
    
        totB total allocated Bytes. This is increased for each allocation with the number of allocated bytes.
    
        totBk total allocated Blocks, maintained similary to totB : +1 for each allocation.
    
        totFdB total Freed Bytes, increased each time a block is released by this ("freeing") stack trace : + nr freed bytes for each free operation.
    
        totFdBk total Freed Blocks, maintained similarly to totFdB : +1 for each free operation.
    
    Note that the last 4 counts are produced only when the --xtree-memory=full was given at startup.
    

    This option will work with various tools, and the resulting file can be visualised a.o. with kcachegrind.

    See https://www.valgrind.org/docs/manual/manual-core.html#opt.xtree-memory and https://www.valgrind.org/docs/manual/manual-core.html#manual-core.xtree for more info.

    You might also experiment with --tool=dhat, a tool specialised to report what your program does with the memory allocated.