在Mac OS X上诊断堆碎片? [英] Diagnosing heap fragmentation on Mac OS X?

查看:105
本文介绍了在Mac OS X上诊断堆碎片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写的Core Foundation应用程序似乎比我实际分配的方式消耗更多的内存(根据Activity Monitor中的"Real Mem"计数).

A Core Foundation app I'm writing seems to be consuming way more memory (according to the "Real Mem" count in Activity Monitor) than I am ever actually allocating.

我已经通过Instruments中的实时字节分配"视图确认了我的实际分配(大约10MB),但是活动监视器中的"Real Mem"计数显示> 60MB,并且显然还在增长.我也已经使用Instruments确认没有泄漏.

I have confirmed my actual allocations are what I expect them to be (about 10MB) via the Live Bytes Allocations view in Instruments, but the "Real Mem" count in Activity Monitor shows > 60MB and apparently growing. I've also confirmed there are no leaks, also using Instruments.

我的应用程序会保留大量大小不一的缓冲区队列,并在添加/删除队列项目时不断释放()和malloc()缓冲区.

My application keeps a large queue of buffers of varying size, and is constantly free()-ing and malloc()-ing buffers as it adds/removes queue items.

已经阅读了一些有关堆碎片的知识,这似乎是对正在发生的事情的一种解释.所以我的问题如下:

Having read a little bit about heap fragmentation, this seems a likely explanation for what is happening. So my questions are as follows:

  1. 是否有任何方法可以在OS X上进行确认,例如也许可以直观地看到堆?
  2. 像Windows一样,OS X是否有可选的低碎片堆管理器?
  1. Is there any way to confirm this on OS X e.g. maybe get a visual representation of the heap?
  2. Is there an optional low fragmentation heap manager for OS X as there is for Windows?

对于任何想复制问题的人,以下示例代码都可以很好地显示相同的症状:

For anyone who wants to replicate the problem, the following example code shows up the same symptoms quite nicely:

#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的进程内存使用量.

If you remove the random element from the above code, you get around 10MB process memory usage as expected.

推荐答案

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

The heap is a complicated data structure and what you're seeing is normal. Just because you free() a buffer does not mean that the library is returning that memory to the OS. System calls have a cost, so when the allocation system is asking for a chunk of memory it tends to ask for more than it needs so that subsequent allocations can return memory without going to the kernel. The heap also likely maintains several allocation regions for different allocation sizes to avoid long searches and fragmentation. By making allocations of random sizes, you've managed to initialize several of these buckets.

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

There is no way for you to anticipate the behavior of the memory allocation subsystem or other system libraries you link against, and therefore Activity Monitor or top or any other tool will not give you meaningful information. If you want to track memory allocations or leaks, use a malloc debugger or a tool like valgrind.

这篇关于在Mac OS X上诊断堆碎片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆