You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么64位Windows系统无法分配大容量虚拟内存?

问题描述

在支持虚拟内存的系统上,理论上可分配远超物理RAM容量的地址空间,仅在实际写入数据时才会占用物理内存。
32位系统的虚拟地址空间上限为4GB,该限制在64位系统上本应不存在。
尽管Windows未使用完整64位地址空间,目前仅用44位,对应容量仍达16TB,因此分配1TB地址空间理应无问题。
为此我编写了测试程序,尝试以每次10GB的粒度分配1TB地址空间,代码如下:

#include <new>
#include <stdio.h>

void main() {
  std::set_new_handler([]() {
    perror("new");
    exit(1);
  });
  for (int i = 0; i < 100; i++) {
    auto p = new char[10ULL << 30];
    printf("%p\n", p);
  }
}

该程序在配备32GB RAM的Windows x64系统上运行,得到如下结果(每次运行的具体地址有差异,但整体表现一致):

0000013C881C1040
0000013F081D0040
00000141881E2040
00000144081F1040
0000014688200040
0000014908219040
0000014B88226040
0000014E08232040
0000015088246040
0000015308252040
0000015588260040
new: Not enough space

程序仅成功分配110GB就报错退出,该容量虽大于物理RAM,但远低于理论可用地址空间上限。
可以确认程序并未对分配的内存执行写入操作(写入操作需要分配物理内存,我测试过分配后立即调用memset写入,程序运行速度会明显变慢,符合预期)。
请问该虚拟内存分配限制的来源是什么?

问题解答

核心原因是标准C++的new操作符在Windows平台的默认行为和预期不一致:它会同时完成地址空间保留和内存页提交两个动作,而非仅保留地址空间,因此分配量会受到系统*提交限制(Commit Charge Limit)*的约束,这个限制的总大小等于物理内存容量 + 系统配置的页面文件总容量。

  • 测试机物理内存为32GB,按测得的110GB分配上限推算,当前系统的页面文件总大小约为70~80GB,两者相加刚好和测试结果吻合。
  • 提交限制是Windows的内存保障机制:所有已提交的内存,不管用户有没有写入数据,系统都会预留对应的后备存储(物理内存或页面文件空间),确保后续写入操作不会因为没有存储资源失败,因此总提交量永远不能突破物理内存+页面文件的总大小,和用户是否写入没有关系。

如果要单独测试地址空间的分配上限,不要使用标准new,直接调用Windows原生API VirtualAlloc,仅指定MEM_RESERVE标志,这个操作只会占用进程的地址空间,不会计入提交计数,就能分配到接近16TB的地址空间,符合理论上限。

内容的提问来源于stack exchange,提问作者rwallace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 10:45:02