【问题标题】:malloc/realloc/free capacity optimizationmalloc/realloc/free 容量优化
【发布时间】:2012-02-22 03:25:08
【问题描述】:

当您有一个动态分配的缓冲区在运行时以不可预知的方式(例如向量或字符串)改变其大小时,优化其分配的一种方法是仅在 2 的幂(或其他一些集合)上调整其后备存储的大小边界/阈值),并保留未使用的额外空间。这有助于分摊搜索新的空闲内存和复制数据的成本,但会消耗一点额外的内存。例如,许多 C++ stl 容器的接口规范(reserve vs resize vs trim)都有这样的方案。

我的问题是,Linux 3.0 x86_64、GLIBC 2.13、GCC 4.6 (Ubuntu 11.10) 上的 malloc/realloc/free 内存管理器的默认实现是否有这样的优化?

void* p = malloc(N);
... // time passes, stuff happens
void* q = realloc(p,M);

换句话说,对于 N 和 M 的什么值(或在什么其他情况下)p == q?

【问题讨论】:

    标签: linux memory gcc glibc allocation


    【解决方案1】:

    来自http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=12d2211b0d6603ac27840d6f629071d1c78586fe;hb=HEADglibc 主干中的 realloc 实现

    首先,如果内存是通过 mmap() 而不是 sbrk() 获得的,glibc malloc 对大型请求执行此操作,则默认情况下 IIRC >= 128 kB:

    
       if (chunk_is_mmapped(oldp))
       {
         void* newmem;
    
     #if HAVE_MREMAP
         newp = mremap_chunk(oldp, nb);
         if(newp) return chunk2mem(newp);
     #endif
         /* Note the extra SIZE_SZ overhead. */
         if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
         /* Must alloc, copy, free. */
         newmem = public_mALLOc(bytes);
         if (newmem == 0) return 0; /* propagate failure */
         MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
         munmap_chunk(oldp);
         return newmem;
       }
    

    (Linux 有 mremap(),所以在实践中就是这样做的)。

    对于较小的请求,我们有以下几行

    newp = _int_realloc(ar_ptr, oldp, oldsize, nb);
    

    _int_realloc 在此处复制粘贴有点大,但您会发现它从上面链接的第 4221 行开始。 AFAICS,它不会做常数因子优化增加,例如C++ std::vector 确实如此,而是准确分配用户请求的数量(四舍五入到下一个块边界 + 对齐的东西等等)。

    我想这个想法是,如果用户希望这个因子增加 2 倍(或任何其他恒定因子增加以保证多次调整大小时的对数效率),那么用户可以自己在设施顶部实现它由 C 库提供。

    【讨论】:

      【解决方案2】:

      也许您可以使用malloc_usable_size (google for it) 来通过实验找到答案。但是,此功能似乎没有记录,因此您需要检查它是否仍可在您的平台上使用。

      另见How to find how much space is allocated by a call to malloc()?

      【讨论】:

        猜你喜欢
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-27
        • 1970-01-01
        • 1970-01-01
        • 2019-09-19
        • 1970-01-01
        相关资源
        最近更新 更多