在Mac OS X上诊断堆碎片?

时间:2012-02-09 00:16:06

标签: c++ c macos memory-management heap

我正在编写的Core Foundation应用程序似乎消耗了更多的内存(根据" Real Mem"在Activity Monitor中计算),而不是我实际分配的内存。

我已通过Instruments中的Live Bytes Allocations视图确认我的实际分配是我期望的(大约10MB),但是" Real Mem"计数活动监视器显示> 60MB并且显然在增长。我也确认没有泄漏,也使用仪器。

我的应用程序保留了大量不同大小的缓冲区队列,并且在添加/删除队列项时始终是free()和malloc()缓冲区。

阅读了一些关于堆碎片的内容,这似乎可以解释正在发生的事情。所以我的问题如下:

  1. 有没有办法在OS X上确认这一点,例如也许得到堆的直观表示?
  2. 对于OS X,是否有可选的低碎片堆管理器,因为它适用于Windows?
  3. 对于想要复制问题的任何人,以下示例代码显示相同的症状:

    #define MAX_SIZE (10*1024*1024)
    
    int main (int argc, const char * argv[])
    {
    
    size_t actual_alloc=0;
    size_t max_alloc=0;
    
    char *bigbuf=NULL;
    size_t bigsize=0;
    
    for  (long x=0; x<10000000; x++)
    {
        if (bigbuf!=NULL)
        {
            actual_alloc -= bigsize;
            free(bigbuf);
        }
    
        bigsize = rand() % MAX_SIZE; // alloc random amount up to MAX_SIZE
        bigbuf = (char*)malloc(bigsize);
        memset(bigbuf, 'x', bigsize);
        actual_alloc += bigsize;
    
        if (actual_alloc > max_alloc)
            max_alloc = actual_alloc;
    
        if (x%100==0)
        {
            printf("alloc = %u \t max = %u\n", 
                 (unsigned long)actual_alloc, (unsigned long)max_alloc);
    
            // max_alloc tends towards 10MB, 
            //  "Real Mem" in activity monitor tends towards 60MB
        }
    }
    
    
    return 0;
    }
    

    如果从上面的代码中删除随机元素,则可以按预期获得大约10MB的进程内存使用量。

1 个答案:

答案 0 :(得分:2)

堆是一个复杂的数据结构,你所看到的是正常的。仅仅因为你的free()缓冲区并不意味着库正在将该内存返回给操作系统。系统调用有成本,所以当分配系统要求一块内存时,它往往会要求的内存超过它所需要的,以便后续分配可以返回内存而无需进入内核。堆还可能为不同的分配大小维护多个分配区域,以避免长搜索和碎片。通过分配随机大小,您已经设法初始化了其中几个桶。

您无法预测内存分配子系统或您链接的其他系统库的行为,因此Activity Monitor或top或任何其他工具不会为您提供有意义的信息。如果要跟踪内存分配或泄漏,请使用malloc调试器或valgrind之类的工具。