为什么解除分配堆内存要比分配它慢得多?

Ama*_*rab 5 c++ memory memory-management heap-memory

这是一个经验假设(分配比解除分配更快).

这也是我猜的原因之一,为什么基于堆的存储(如STL容器或其他)选择不将当前未使用的内存返回给系统(这就是为什么缩小适应成语诞生的原因).

当然,我们不应该混淆' '内存与' '类似的数据结构.


那么为什么解除分配速度较慢

它是Windows特定的(我在Win 8.1上看到它)还是OS独立的?

是否有一些C++特定的内存管理器自动涉及使用' new '/' delete '或整个mem.管理完全依赖于操作系统?(我知道C++ 11引入了一些垃圾收集支持,我从未真正使用过,更好地依赖于旧堆栈静态持续时间或自我管理容器RAII).

另外,在FOLLY字符串的代码中,我看到使用旧的C堆分配/解除分配,它是否比C++' new '/' delete ' 快?


PS请注意,问题不是关于虚拟内存机制,我知道用户空间程序没有使用真正的内存.addresation.

Jer*_*fin 2

我和@Basile 的想法非常相似:我想知道你的基本假设是否实际上(甚至接近)正确。由于您标记了问题 C++,所以我用 C++ 编写了一个快速基准测试。

#include <vector>
#include <iostream>
#include <numeric>
#include <chrono>
#include <iomanip>
#include <locale>

int main() {
    std::cout.imbue(std::locale(""));

    using namespace std::chrono;
    using factor = microseconds;

    auto const size = 2000;

    std::vector<int *> allocs(size);

    auto start = high_resolution_clock::now();

    for (int i = 0; i < size; i++)
        allocs[i] = new int[size];

    auto stop = high_resolution_clock::now();
    auto alloc_time = duration_cast<factor>(stop - start).count();

    start = high_resolution_clock::now();

    for (int i = 0; i < size; i++)
        delete[] allocs[i];

    stop = high_resolution_clock::now();

    auto del_time = duration_cast<factor>(stop - start).count();

    std::cout << std::left << std::setw(20) << "alloc time: " << alloc_time << " uS\n";
    std::cout << std::left << std::setw(20) << "del time: " << del_time << " uS\n";
}
Run Code Online (Sandbox Code Playgroud)

我还在 Windows 上使用 VC++,而不是 Linux 上的 gcc。但结果并没有太大不同:释放内存所花费的时间比分配内存所花费的时间要少得多。以下是连续三轮运行的结果。

alloc time:         2,381 uS
del time:           1,429 uS

alloc time:         2,764 uS
del time:           1,592 uS

alloc time:         2,492 uS
del time:           1,442 uS
Run Code Online (Sandbox Code Playgroud)

然而,我警告说,分配和释放(主要)由标准库处理,因此一个标准库和另一个标准库之间可能会有所不同(即使使用相同的编译器)。我还注意到,如果这在多线程代码中有所改变,我不会感到惊讶。虽然这实际上并不正确,但似乎有一些作者存在误解,认为在多线程环境中释放需要锁定堆以进行独占访问。这是可以避免的,但这样做的方法并不一定是显而易见的。