如何在Windows上获得一个页面表精明的realloc()?

时间:2014-12-23 20:42:25

标签: winapi memory-management paging realloc virtual-memory

This question/answer表示现代虚拟内存操作系统上的某些realloc实现操作页表而不是实际复制数据。

对于使用大型数组的程序来说,这显然是理想的。如果您的计算机具有16GB内存并且您希望将8GB阵列增加到10GB,则基于页面表的realloc可以快速工作,而复制realloc则需要向磁盘分页。 / p>

我在Windows 7(MSVC 2013)和OS X 10.8 Mountain Lion(Clang ++ 2.79)上编译并运行了以下程序。两台机器都有16 GB的内存。编译器正在O2进行优化。我添加了写入以防止优化和过度使用技巧。

#include <stdlib.h>

size_t const GIG = 1000 * 1000 * 1000;
size_t const BIG = 4 * GIG;
size_t const HUGE = 6 * GIG;

int main()
{
    char *mem = (char *)malloc(BIG);
    for (size_t i = 0; i < BIG; ++i) {
        mem[i] = i & 0xFF;
    }
    mem = (char *)realloc(mem, HUGE);
    for (size_t i = BIG; i < HUGE; ++i) {
        mem[i] = i & 0xFF;
    }
    free(mem);
}

在Windows上,资源监视器中进程的提交值达到10GB。在OS X上,活动监视器中进程的虚拟内存值不超过6GB。

如果我将BIG更改为8GB且HUGE更改为10GB,那么它们的总数大于物理内存,则Windows版本会使系统陷入磁盘分页,而OSX版本则不会

这些测试表明Windows realloc复制数据,OS X realloc操纵页面表。

我没有Linux机器,但是this blog post通过glibc和Linux源代码来证明Linux realloc操纵大型数组的页表。

This blog post注意到Windows的慢realloc,但是作者通过更改程序而不是使用不同的分配器来解决它。

必须有一些方法可以在Windows上获得理想的页表行为。是否有提供它的不同内存分配API?

编辑这会有用吗?对于每个巨大的阵列,使用VirtualAlloc保留整个系统内存大小的虚拟地址范围,然后根据需要提交物理内存。对于处理多个大型数组的程序,只有在地址空间远大于物理内存时,才能使用。但在不久的将来,这似乎是对64位桌面系统的安全假设。即使是当前x64 CPU上的48位地址总线也可以存储281475 GB的内存。

0 个答案:

没有答案