测量函数调用期间的最大内存使用情况

时间:2019-01-21 10:09:13

标签: c++ linux macos getrusage

我有一个Linux / Mac C ++库,该库以函数调用的形式执行一系列步骤。我想测量每个步骤中的最大内存使用量。

我对临时解决方案不感兴趣,例如启动另一个轮询内存使用情况的线程,运行探查器等。

到目前为止,我发现getrusage()在Mac和Linux上都存在,并且确实返回了最大内存使用量,但是似乎没有办法在每次函数调用后重置该最大值。

有没有办法解决这个限制?

编辑:为了清楚起见,我不想指挥malloc() / free()并记录所有内容。我想要一个适合继续运行生产代码的解决方案。

2 个答案:

答案 0 :(得分:0)

我浏览了Linux源代码,发现this

        /*
         * Writing 5 to /proc/pid/clear_refs resets the peak
         * resident set size to this mm's current rss value.
         */

我还没有尝试过,但是看起来很有希望。

编辑:它已添加到this commit

编辑2:我浏览了MacOS内核源代码-相应的值存储在resident_max中。不幸的是,似乎没有重置它的功能。

编辑3:在Linux上,您可以使用malloc_info()获得最大分配的内存,但是似乎没有办法重置它。它还依靠您使用glibc

答案 1 :(得分:0)

mallocfree调用不仅仅是围绕sbrkmmap系统调用的简单包装。这使得getrusage返回的内容与对mallocfree的调用不符。这些功能的任何重要实现都会在考虑将任何内容返回给系统之前,在流程本身内部管理一个空闲列表。

程序将调用free(或为此引起的delete),并且内存不会立即返回操作系统(可能永远不会)。如果free版的内存调用了malloc,则该任务可以重用该任务,但其他进程则不能。从操作系统的角度来看,这getrusage正确,而从程序的角度来看,这是不正确的。

在Linux上,您可以使用mallinfo()

#include <malloc.h>
#include <cinttypes>
std::size_t memsize()
{
    auto data = mallinfo();
    return data.arena - data.fordblks + data.hblkhd;
}

此处,memsize()将返回从程序角度分配的字节数。它考虑了各种分配技术,例如sbrkmmap,并且将舍入和开销作为malloc()(和new)分配的内存的一部分。

使用OSX时,情况并非如此。您可以查看source code of apple's malloc(),尤其是mstats,该注释中注明:

/*
 * A Glibc-like mstats() interface.
 *
 * Note that this interface really isn't very good, as it doesn't understand
 * that we may have multiple allocators running at once.  We just massage
 * the result from malloc_zone_statistics in any case.
 */

这看起来不太理想,并且:

#include <malloc/malloc.h>
#include <cinttypes>
std::size_t memsize()
{
    auto data = mstats();
    return data.bytes_used;
}

根据我的实验,看起来不太好。但这总比没有好,或者仅仅依靠getrusage。我认为您在OSX上不走运,除非有人可以纠正我。