【问题标题】:Strange behavior in 'malloc_stats' function“malloc_stats”函数中的奇怪行为
【发布时间】:2018-11-22 11:22:24
【问题描述】:

我正在使用“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

此时,如果我比较分配前和释放后的“in use bytes”,会有784 bytes的差异。

我不明白发生了什么,我认为“使用中的字节”必须相同......这些字节在哪里?

谢谢。

【问题讨论】:

    标签: c++ memory-management memory-leaks


    【解决方案1】:

    简答

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

    长答案

    如果我们查看 malloc_stats 函数 [1] 的手册页,我们会看到使用中分配消耗的总字节数是由 mallinfo 结构 [2] 的 uordblks 字段获得的,其文档表示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
    

    参考文献

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-03
      • 2011-06-14
      • 2020-01-31
      • 2014-05-24
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多