当我释放内存之前,malloc更快
当我分配和释放内存时,我之后分配最大大小的内存作为以前释放的部分。
可能第二次分配比第一次快吗?
也许是因为它已经知道一个免费的内存区域? 或者因为堆的这部分仍然分配给进程? 还有其他可能的优势吗?
或者它通常没有区别?
编辑:如评论中所述:
- 我对gcc和MSVC特别感兴趣。
- 我的假设是操作系统之前没有“赎回”内存。
由于关于实施的具体细节有很多,我想更清楚地说明这是一个假设的问题。 我不打算滥用这个,但我只是想知道如果这可能发生,假设加速可能是什么原因。
在一些常见的平台上,比如GCC x86_64,有两种malloc()
:小型分配的传统类型,大型的mmap
类型 。 基于mmap
的大型分配将具有较少的相互依赖性。 但是,在某些情况下,传统的小型游戏确实会经历一次大的加速,因为之前的内存是free()
。
这是因为正如你的建议, free()
不会立即将内存返回给操作系统。 实际上它通常不能这样做,因为内存可能位于连续堆的中间。 因此,在许多系统(但不是全部)上,当需要向操作系统请求更多堆空间时, malloc()
只会很慢。
每当您避免进行sbrk
或mmap
等系统调用时,使用malloc
内存分配应该更快。 您至少会保存一个上下文切换 。
使用以下程序进行实验
#include int main() { void* x = malloc(1024*1024); free(x); x = malloc(1024*1024); }
并使用命令strace ./a.out
运行它
当你删除free
电话时,你会注意到另外两个系统电话。
这是我在-O1编译的简单banchmark:
#include #include int main(int argc, char** argv){ for(int i=0;i<10000000;i++){ char volatile * p = malloc(100); if(!p) { perror(0); exit(1); } *p='x'; //free((char*)p); } return 0; }
迭代成本约为60ns,免费 ,约150ns,不在我的Linux上。 是的,免费后的mallocs可以明显更快。
这取决于分配的大小。 这些小尺寸将不会返回到操作系统。 对于2的幂的较大尺寸,glibc malloc开始进行mmaping和unmmapping,然后我预计释放变量会减速。