我正在编写的核心基础应用程序似乎消耗的内存比我实际分配的内存多(根据活动监视器中的“真实内存”计数)。
我已通过 Instruments 中的“实时字节分配”视图确认我的实际分配符合我的预期(大约 10MB),但活动监视器中的“真实内存”计数显示 > 60MB 并且明显在增长。我还使用仪器确认没有泄漏。
我的应用程序保留了一个大小不同的缓冲区的大队列,并且在添加/删除队列项时不断地 free()-ing 和 malloc()-ing 缓冲区。
阅读了一些有关堆碎片的内容后,这似乎是对正在发生的事情的可能解释。所以我的问题如下:
- 有什么方法可以在 OS X 上确认这一点,例如也许可以获得堆的直观表示?
- OS X 是否有与 Windows 一样的可选低碎片堆管理器?
对于任何想要复制该问题的人来说,以下示例代码很好地显示了相同的症状:
#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 的进程内存使用量(如预期)。
堆是一个复杂的数据结构,你所看到的是正常的。仅仅因为您 free() 缓冲区并不意味着库正在将该内存返回给操作系统。系统调用是有成本的,因此当分配系统请求一块内存时,它往往会请求超出其需要的内存,以便后续分配可以返回内存而无需进入内核。堆还可能为不同的分配大小维护多个分配区域,以避免长时间搜索和碎片。通过分配随机大小,您已经成功初始化了其中几个存储桶。
您无法预测内存分配子系统或链接的其他系统库的行为,因此活动监视器或 top 或任何其他工具不会为您提供有意义的信息。如果要跟踪内存分配或泄漏,请使用 malloc 调试器或 valgrind 等工具。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)