当我以前释放内存时,malloc更快

时间:2017-01-26 08:46:12

标签: c memory-management

当我分配并释放内存时,之后我分配最大大小的内存作为以前释放的部分。

可能第二次分配比第一次快吗?

也许是因为它已经知道一个免费的内存区域? 或者因为堆的这部分仍然分配给进程? 还有其他可能的优势吗?

或者它通常没有区别?

编辑:正如评论中所说:

  • 我对gcc和MSVC特别感兴趣。
  • 我的假设是以前操作系统没有“赎回”内存。

由于有很多关于实施的具体细节,我想更清楚地说明这是一个假设的问题。 我不打算滥用这个,但我只是想知道如果这可能发生,假设加速的原因可能是什么。

3 个答案:

答案 0 :(得分:3)

只要您避免进行sbrkmmap等系统调用,malloc的内存分配就会更快。您至少会保存context switch

使用以下程序进行实验

#include <stdlib.h>

int main() {

    void* x = malloc(1024*1024);
    free(x);
    x = malloc(1024*1024);

}

并使用命令strace ./a.out

运行它

当您移除对free的来电时,您会发现另外两个系统调用brk

答案 1 :(得分:3)

在一些常见的平台上,例如GCC x86_64,有两种malloc():小型分配的传统类型和mmap kind for large ones。基于mmap的大型分配将减少相互依赖性。但是在某些情况下,传统的小型游戏确实会经历一次大的加速,因为之前的记忆是free()'。

这是因为正如您所建议的那样,free()不会立即将内存返回给操作系统。实际上它通常不能这样做,因为内存可能位于堆中间是连续的。因此,在许多系统(但不是全部)上,malloc()只有在需要向OS请求更多堆空间时才会变慢。

答案 2 :(得分:2)

这是我在-O1编译的简单banchmark:

#include <stdio.h>
#include <stdlib.h>

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;
}

我的Linux上的迭代成本约为 60ns,免费 150ns,不含。 是的,免费后的mallocs可以明显更快。

这取决于分配的大小。这些小尺寸将不会返回到操作系统。对于功率为2的较大尺寸,glibc malloc开始进行mmaping和unmmapping,然后我预计释放变量会减速。