我正在使用'malloc_stats'函数进行一些测试,并且看到了我不理解的奇怪行为。测试非常简单,我正在做的是分配内存,并在分配之前,分配之后和释放内存之后打印“ malloc_stats”。这是我正在使用的代码:
int main(int argc, char *argv[])
{
char *alloc[MAX_ALLOCS];
if ( argc < 3 or strcmp(argv[1], "--help") == 0 ) {
cout << argv[0] << " num-blocks block-size [free-step [start-free [end-free]]]" << endl;
return 1;
}
int numBlocks = atoi(argv[1]);
size_t blockSize = atoi(argv[2]);
int freeStep = (argc > 3) ? atoi(argv[3]) : 1;
int freeBegin = (argc > 4) ? atoi(argv[4]) : 0;
int freeEnd = (argc > 5) ? atoi(argv[5]) : numBlocks;
cout << "============== Before allocating blocks ==============" << endl;
malloc_stats();
for (int j = 0; j < numBlocks; j++)
{
alloc[j] = (char*) malloc(blockSize);
if (alloc[j] == NULL) {
cout << "ERROR: malloc" << endl;
return 1;
}
}
cout << endl << "============== After allocating blocks ==============" << endl;
malloc_stats();
for (int j = freeBegin; j < freeEnd; j += freeStep) {
free(alloc[j]);
}
cout << endl << "============== After freeing blocks ==============" << endl;
malloc_stats();
return 1;
}
这是我得到的输出:
./exe 1000 100 1
============== Before allocating blocks ==============
Arena 0:
system bytes = 135168
in use bytes = 74352
Total (incl. mmap):
system bytes = 135168
in use bytes = 74352
max mmap regions = 0
max mmap bytes = 0
============== After allocating blocks ==============
Arena 0:
system bytes = 270336
in use bytes = 186352
Total (incl. mmap):
system bytes = 270336
in use bytes = 186352
max mmap regions = 0
max mmap bytes = 0
============== After freeing blocks ==============
Arena 0:
system bytes = 270336
in use bytes = 75136
Total (incl. mmap):
system bytes = 270336
in use bytes = 75136
max mmap regions = 0
max mmap bytes = 0
在这一点上,如果我比较分配之前和释放之后的“使用中字节”,则差异为 784字节。
我不知道发生了什么,我以为“使用中的字节”必须相同...这些字节在哪里?
谢谢。
答案 0 :(得分:3)
此字节数差异与操作系统使用的分页有关,而不是内存泄漏。当分配的块大小不是页面大小的倍数时,分配的一些额外内存将不会释放。额外的内存以后可以由分配器使用,并且不会泄漏。
如果我们查看malloc_stats
函数[1]的手册页,则会发现正在使用的分配所消耗的字节总数是通过mallinfo结构的uordblks
字段获得的[ 2],其文档显示uordblks
是分配的总字节数。在这里,分配并不一定意味着您将所有这些内存都用作应用程序程序员。如果分配器可导致更高的性能和效率,则分配的内存可能会比出于对齐目的而请求的内存更多。
这是您的问题中描述的问题。您将程序运行为
./exe 1000 100 1
其中1000是块数,100是块大小。由于100不是操作系统使用的页面大小的倍数,因此malloc分配的内存往往会比您在每次调用中请求的更多。
为了快速查看是否确实如此,我们可以分配等于操作系统页面大小的块大小。在Linux发行版中,可以通过以下shell命令获取页面大小:
getconf PAGE_SIZE
在我的情况下返回4096。当我以以下方式运行您的程序
./exe 100 4096 1
我得到以下输出:(请注意,解除分配后的使用中字节与分配之前的使用中字节相同)
============== Before allocating blocks ==============
Arena 0:
system bytes = 135168
in use bytes = 74352
Total (incl. mmap):
system bytes = 135168
in use bytes = 74352
max mmap regions = 0
max mmap bytes = 0
============== After allocating blocks ==============
Arena 0:
system bytes = 540672
in use bytes = 485552
Total (incl. mmap):
system bytes = 540672
in use bytes = 485552
max mmap regions = 0
max mmap bytes = 0
============== After freeing blocks ==============
Arena 0:
system bytes = 208896
in use bytes = 74352
Total (incl. mmap):
system bytes = 208896
in use bytes = 74352
max mmap regions = 0
max mmap bytes = 0