当你有一个dynamic分配的缓冲区,以不可预知的方式在运行时改变其大小(例如向量或string)时,优化其分配的一种方法是只调整其后备存储的权限2(或其他一组边界/阈值),并保留未使用的额外空间。 这有助于分摊search新的空闲内存和复制数据的代价,但需要额外使用一些内存。 例如,许多C ++ stl容器的接口规范(reserve vs resize vs trim)都有这样一个scheme。
我的问题是Linux 3.0 x86_64,GLIBC 2.13,GCC 4.6(Ubuntu 11.10)上的malloc / realloc / free内存pipe理器的默认实现是否有这样的优化?
void* p = malloc(N); ... // time passes, stuff happens void* q = realloc(p,M);
换句话说,对于N和M(或者在其他情况下)的值是什么,p == q?
从glibc中的realloc实现,在http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=12d2211b0d6603ac27840d6f629071d1c78586fe;hb=HEAD
首先,如果已经通过mmap()而不是sbrk()获得了内存,那么glibc malloc可以处理大量请求,默认情况下大于等于128 kB IIRC:
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库。
也许你可以使用malloc_usable_size
( 谷歌为它 )实验找到答案。 然而,这个函数似乎没有文档,所以你需要检查它是否在你的平台上仍然可用。
另请参见如何查找通过调用malloc()分配多少空间?