标签:memory gcc glibc allocation linux
如果您有一个动态分配的缓冲区,它在运行时以无法预测的方式(例如向量或字符串)改变其大小,则优化分配的一种方法是仅以2的幂(或其他一些边界/阈值),并保留多余的空间.这有助于分摊寻找新的可用内存和复制数据的成本,但要花一点额外的内存.例如,许多C stl容器的接口规范(保留vs调整大小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?
解决方法:
来自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会针对大型请求执行此操作,默认情况下,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库.
标签:memory,gcc,glibc,allocation,linux 来源: https://codeday.me/bug/20191201/2083529.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。