malloc/realloc/free 容量优化
当您有一个动态分配的缓冲区,在运行时以不可预测的方式(例如向量或字符串)改变其大小时,优化其分配的一种方法是仅按 2 的幂(或其他一组边界/阈值),并保留多余的空间未使用。这有助于分摊搜索新的可用内存和复制数据的成本,但会消耗一点额外的内存。例如,许多 C++ stl 容器的接口规范(保留、调整大小、修剪)都考虑了这样的方案。
我的问题是 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 ?
When you have a dynamically allocated buffer that varies its size at runtime in unpredictable ways (for example a vector or a string) one way to optimize its allocation is to only resize its backing store on powers of 2 (or some other set of boundaries/thresholds), and leave the extra space unused. This helps to amortize the cost of searching for new free memory and copying the data across, at the expense of a little extra memory use. For example the interface specification (reserve vs resize vs trim) of many C++ stl containers have such a scheme in mind.
My question is does the default implementation of the malloc/realloc/free memory manager on Linux 3.0 x86_64, GLIBC 2.13, GCC 4.6 (Ubuntu 11.10) have such an optimization?
void* p = malloc(N);
... // time passes, stuff happens
void* q = realloc(p,M);
Put another way, for what values of N and M (or in what other circumstances) will p == q?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
来自 glibc trunk 中的 realloc 实现
首先,如果内存是通过mmap()而不是通过mmap()获取的sbrk(),glibc malloc 对大请求执行的操作,默认情况下 >= 128 kB IIRC:
(Linux 有 mremap(),所以实际上就是这么做的)。
对于较小的请求,下面几行
_int_realloc 有点大,无法复制粘贴到此处,但您会发现它从上面链接中的第 4221 行开始。 AFAICS,它不会像 C++ std::vector 那样进行常数因子优化增加,而是精确分配用户请求的数量(四舍五入到下一个块边界+对齐内容等)。
我想这个想法是,如果用户想要 2 倍大小增加(或任何其他常数因子增加,以保证多次调整大小时的对数效率),那么用户可以在由C 库。
From the realloc implementation in glibc trunk at http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=12d2211b0d6603ac27840d6f629071d1c78586fe;hb=HEAD
First, if the memory has been obtained via mmap() instead of sbrk(), which glibc malloc does for large requests, >= 128 kB by default IIRC:
(Linux has mremap(), so in practice this is what is done).
For smaller requests, a few lines below we have
where _int_realloc is a bit big to copy-paste here, but you'll find it starting at line 4221 in the link above. AFAICS, it does NOT do the constant factor optimization increase that e.g. the C++ std::vector does, but rather allocates exactly the amount requested by the user (rounded up to the next chunk boundaries + alignment stuff and so on).
I suppose the idea is that if the user wants this factor of 2 size increase (or any other constant factor increase in order to guarantee logarithmic efficiency when resizing multiple times), then the user can implement it himself on top of the facility provided by the C library.
也许你可以使用
malloc_usable_size
(google 一下 )通过实验寻找答案。然而,此功能似乎没有文档记录,因此您需要检查它是否在您的平台上仍然可用。另请参阅如何查找如何调用 malloc() 分配了多少空间?
Perhaps you can use
malloc_usable_size
(google for it) to find the answer experimentally. This function, however, seems undocumented, so you will need to check out if it is still available at your platform.See also How to find how much space is allocated by a call to malloc()?