“malloc_stats"函数中的奇怪行为 [英] Strange behavior in 'malloc_stats' function

查看:102
本文介绍了“malloc_stats"函数中的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 'malloc_stats' 函数做一些测试,我看到了一个我不明白的奇怪行为.测试非常简单,我正在做的是分配内存并在分配之前,分配之后和释放内存之后打印'malloc_stats'.这是我正在使用的代码:

I'm doing some tests with 'malloc_stats' function and I've seen a strange behavior that I don't understand. The test is very easy, what I'm doing is allocate memory and print the 'malloc_stats' before the allocation, after the allocation and after free the memory. This is the code I'm using:

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

此时,如果比较分配前和释放后的in use bytes",相差784 bytes.

At this point, if I compare the "in use bytes" before the allocation and after the freeing, there is a difference of 784 bytes.

我无法理解发生了什么,我认为使用中的字节"必须相同……这些字节在哪里?

I cannot understand what is happening, I supposed that the 'in use bytes' had to be the same... where are these bytes?

谢谢.

推荐答案

简短回答

这种字节数差异与操作系统使用的分页有关,而不是内存泄漏.当您分配的块大小不是页面大小的倍数时,不会释放一些已分配的额外内存.这个额外的内存可以在以后被分配器使用,并且不会泄漏.

Short Answer

This discrepancy in the number of bytes is related to paging used by the operating systems, and is not a memory leak. When you allocate block sizes that are not multiple of the page size, some of the extra memory allocated are not freed. This extra memory can later be used by the allocator, and is not leaked.

如果我们查看malloc_stats函数[1]的手册页,我们会看到使用中分配消耗的总字节数由uordblks获得mallinfo 结构体 [2] 的字段,其文档说 uordblks 是分配的总字节数.在这里,已分配并不一定意味着您作为应用程序员使用了所有这些内存.如果分配器能带来更高的性能和效率,它可能会分配比出于对齐目的而请求的更多内存.

If we check the manual page of the malloc_stats function [1], we see that the total number of bytes consumed by in-use allocations is obtained by the uordblks field of the mallinfo struct [2] whose documentation says that uordblks is the number of total allocated bytes. Here, allocated does not necessarily mean that all of this memory is used by you as the application programmer. Allocator may allocate more memory than was requested for alignment purposes if it leads to higher performance and efficiency.

这是您问题中描述的问题.你运行你的程序

This is the issue described in your question. You run your program as

./exe 1000 100 1

其中 1000 是块数,100 是块大小.由于 100 不是操作系统使用的页面大小的倍数,因此 malloc 将倾向于分配比您每次调用请求更多的内存.

where 1000 is the number of blocks and 100 is the block size. Since 100 is not a multiple of the page size used by the operating system, malloc will tend to allocate more memory than you request on each call.

为了快速检查是否确实如此,我们可以分配与操作系统页面大小相等的块大小.在 Linux 发行版上,可以通过以下 shell 命令获取页面大小:

As a quick check to see that this is indeed the case, we can allocate block sizes that are equal to the page size of our operating system. On Linux distributions, page size can be obtained by the following shell command:

getconf PAGE_SIZE

在我的情况下返回 4096.当我运行你的程序时

which returns 4096 on my case. When I run your program as

./exe 100 4096 1

我得到以下输出:(注意释放完成后使用的字节与分配前使用的字节相同)

I get the following as output: (note that the in-use bytes after the deallocation is finished is the same as the in-use bytes before the allocation)

============== 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

参考文献

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