1. 先搞清楚:虚拟内存到底是干嘛的
1.1 物理内存不够时,系统是怎么“变出”更多内存的
很多第一次接触“虚拟内存”的人会被这个词吓到,以为又是什么高深莫测的底层机制。其实你可以把它理解成一个“仓库”:物理内存是办公桌,程序正在用的东西放在桌面上,存取最快;虚拟内存是办公桌旁边的柜子,桌面放不下的东西先放柜子里,要用的时候再从柜子里取出来摆到桌面上。
Windows 里的虚拟内存,本质上是“物理内存 + 页面文件(pagefile.sys)”的组合。页面文件是存放在硬盘上的一个隐藏系统文件,默认在 C 盘根目录。当物理内存不够的时候,Windows 会把一部分暂时用不到的内存数据挪到这个文件里,腾出物理内存给正在运行的程序用。进程访问内存时,需要的地址是虚拟地址,由系统的内存管理器(Memory Manager)把虚拟地址映射到物理内存或者页面文件里,这一切对普通程序来说是无感的。
这几年 OOM(Out Of Memory,内存不足)出现得越来越频繁,真不是错觉。浏览器开几十个标签页、Electron 套壳应用(比如各种聊天工具、编辑器)、Docker 容器、Java 服务端程序、前端编译工具链,随便一个都能吃掉几个 GB 内存。物理内存不够时,页面文件就成了最后的“安全垫”。一旦页面文件和物理内存同时耗尽,系统就会弹出“系统资源不足,无法完成请求的服务”,或者直接杀掉某个进程,甚至蓝屏,这就是我们常说的 OOM。
1.2 为什么 OOM 越来越常见,跟 Windows 默认设置有什么关系
Windows 默认开启了“自动管理所有驱动器的分页文件大小”,这个策略正常情况下够用,但有两个致命问题。
第一,自动托管的分页文件大小是动态的,它会随着内存使用率上升而增长,也会在压力解除后自动收缩。这种动态增长的过程需要不断扩展 pagefile.sys 文件,磁盘空间不够时,页面文件没法继续变大,于是系统在物理内存耗尽后只能干瞪眼,直接把进程杀掉。
第二,自动托管倾向于把页面文件放在系统盘,也就是 C 盘。C 盘剩余空间不足是 Windows 用户的常态,尤其那些把软件、桌面文件、下载目录全放在 C 盘的人。页面文件没空间扩展,内存压力一来,OOM 就出现了。另外有些优化软件会把虚拟内存改成 0,想“强制程序使用物理内存”,这就是纯粹的毒瘤操作,去掉页面文件后 Windows 内核的很多映射机制会变得非常脆弱,表现就是大程序频繁崩溃、蓝屏。
1.3 虚拟内存不足 vs 物理内存不足,怎么分清楚
很多人一看到“内存不足”就认定要加内存条,结果加了内存问题还在,说明没分清两种“内存不足”。
| 项目 | 物理内存不足 | 虚拟内存不足 |
|---|---|---|
| 本质 | 物理内存条容量无法满足当前负载 | 虚拟内存整体地址空间(物理内存+页面文件)不够 |
| 典型表现 | 系统整体卡顿,任务管理器显示内存占用接近 100% | 程序瞬间崩溃、报“内存不足”错误,但物理内存可能还有空闲 |
| 常见来源 | 开的程序太多、单个程序吃内存太大 | 页面文件被禁用、大小被限制过长、C 盘空间不足导致 pagefile 无法扩展 |
| 解决思路 | 加物理内存、减少常驻程序、压缩内存占用 | 恢复页面文件、调整为合理大小、迁移到空间充足的磁盘 |
这里最关键的是第二类:虚拟内存不足时,物理内存往往还有余量,但系统还是报错。原因是某些程序的虚拟地址空间需求远超物理内存,比如大型编译任务、大型数据库实例、Docker 多容器叠加运行,它们需要大量连续虚拟地址空间。这时候你加再多的内存条也没用,必须给页面文件一个合理的容量上限。
2. 配置前的关键准备:先看清当前系统状态
2.1 怎么看虚拟内存当前大小,两种方法都给你
配置之前,先看看自己电脑现在是什么样的。最简单的方式是任务管理器。
打开任务管理器,切到“性能”选项卡,选中“内存”,左下角能看到“已提交”和“分页缓冲池”这类指标。其中“提交费用”里有一项“限制”,这个数值就是系统当前允许的最大虚拟内存总量(物理内存 + 所有页面文件的最大值)。如果你的“已提交”长期逼近“限制”,说明虚拟内存压力很大。
另一种是看具体页面文件大小的准确方法,进系统属性。右键“此电脑”选“属性”,在打开的窗口右侧点“高级系统设置”,弹出窗口里切到“高级”选项卡,在“性能”区域点“设置”,再切到“高级”选项卡,最底部就是“虚拟内存”,点“更改”就能看到所有磁盘的页面文件分配情况。
值得说一句,“怎么看虚拟内存”这个问题太普遍了,很多教程直接让你命令一行搞定,但图形界面里的信息更直观,适合大多数人。更专业一点可以按 Win+R 输入perfmon.msc打开性能监视器,添加计数器:“Memory\Committed Bytes”(已提交字节数)和“Memory\Commit Limit”(提交限制),用折线图看压力变化,这个后面验证效果时还要用。
2.2 分清三种管理模式:系统托管、自定义、无页面文件
Windows 的虚拟内存设置界面里有三种选择:系统托管的大小、自定义大小、无分页文件。
“系统托管的大小”就是系统自动调整每个盘的页面文件,默认策略,不用自己操心,但前面说了,动态增长有延迟,压力突发时扩展不够快,而且可能因为 C 盘空间不足而失效。
“自定义大小”就是手动指定初始大小和最大值。这是多数老手最推荐的方式,好处有两个:一是页面文件可以固定大小或固定在某个区间内,避免频繁扩展产生的碎片和卡顿;二是可以明确把页面文件放到空间充足、读写性能好的磁盘上。
“无分页文件”就是在这个盘上完全不放 pagefile.sys,这样做通常是为了某个盘空间紧张时腾位置,但至少要保持在某一个盘上有页面文件,否则系统就会退回到“完全依赖物理内存”,OOM 概率会显著上升。注意,如果你在 C 盘设置了“无分页文件”,系统会让你确认,并且可能会在其他盘自动生成一个临时页面文件,这是正常保护机制,不是配置错误。
3. 到底该设多大?从 16G 到 32G 的实操建议
3.1 一个靠谱的初始大小与最大值,怎么算
围绕“16G 内存虚拟内存设置多少”“32GB 分配多少虚拟内存”这种问题的答案五花八门,很多老教程还在推荐“初始 1.5 倍物理内存,最大 3 倍物理内存”,那是最早机械硬盘时代流传下来的过时方案。现在内存普遍 16G 起跳,SSD 普及率极高,再按 1.5 倍去设等于给 C 盘挖坑。
我目前给多数机器的配置原则是:初始大小 = 物理内存的 0.5 到 1 倍,最大值 = 物理内存的 1 到 1.5 倍,具体看用途。这里我整理了一张表,可以直接参考:
| 物理内存 | 日常办公、网页浏览 | 轻量开发(IDE + 浏览器) | 重量级构建 / 虚拟机 / Docker / 数据库 |
|---|---|---|---|
| 8 GB | 初始 2048MB,最大 4096MB | 初始 4096MB,最大 8192MB | 初始 8192MB,最大 16384MB |
| 16 GB | 初始 2048MB,最大 4096MB | 初始 4096MB,最大 8192MB | 初始 8192MB,最大 24576MB |
| 32 GB | 可以不设页面文件,或设置 1024MB 左右 | 初始 2048MB,最大 4096MB | 初始 8192MB,最大 32768MB |
| 64 GB 以上 | 可以不设,或按需设置 1024MB | 建议保持系统托管或 2048MB 固定 | 视具体应用而定,通常不需要太大 |
表格只是参考,真正决定大小的是你自己的工作负载。16G 内存的机器跑 Docker 多容器、编译 Android 项目、开 Android Studio 加模拟器,那么把最大上限拉到 24G 甚至 32G 都不夸张。32G 内存的人如果只是办公聊天,其实可以设置一个很小的页面文件或者直接系统托管,没必要傻乎乎配一个 64G 的文件占硬盘。
3.2 SSD 上的虚拟内存:能不能关?要不要固定大小?
SSD 普及以后,关于页面文件最大的争议就是“它会不会伤 SSD”。平心而论,页面文件确实会产生写入,但系统只有当物理内存不够时才会把页面文件当临时存放区,正常负载下写入量很有限,不值得为了“保护 SSD”去关掉页面文件,那样做因小失大。
如果你用的是 SSD,建议直接把页面文件设为固定大小,就是让初始大小和最大值相同,这样系统就不会反复扩展和收缩文件,减少无谓写入,也从根源上避免了“扩展失败导致的 OOM”。代价是页面文件会一直占用固定大小的空间,所以建议放在剩余空间充裕的盘里。
这里有个容易被忽略的技巧:如果你的系统盘是 SSD、数据盘是机械硬盘 HDD,不要把页面文件放到 HDD 上。页面文件本身的读取速度非常影响内存不足时的整体体验,放 HDD 上会让系统在内存压力大的时候卡到没法用。反过来,如果你有两块 SSD,把页面文件放在读写快的那个上,尤其是系统盘之外的从盘,往往效果最好。
3.3 常见误区:虚拟内存越大越好?放哪个盘最好?
先说“越大越好”这个误区。虚拟内存的上限受系统位数限制,64 位 Windows 的虚拟地址空间上限很大,但页面文件设置过大有两个问题:一是浪费磁盘空间;二是如果初始值设得很大,Windows 会把这个大小的文件空间全部保留,你可能没意识到一个 pagefile.sys 就占了 20G 到 30G。真正合理的做法是设置一个“够用且有安全余量”的上限,而不是盲目追求大。
再说放哪个盘。虽然是西瓜都能放页面文件,但要避免放在系统和程序同一块盘上吗?这个说法在机械硬盘时代成立,因为两个盘相互独立可以分散 IO 压力。但到了 SSD 时代,放同一个盘影响不大,更值得关注的是盘的剩余空间容不容得下页面文件的最大值。如果你设置的最大值是 24G,但盘只剩 15G,系统会在达到物理内存上限前就陷入困境。
我个人习惯是:C 盘保留系统托管的“小文件”或固定 1024MB 的页面文件,防止某些强制要求 C 盘有 pagefile 的程序(比如某些调试器、系统工具)出错;把主要的大型页面文件放在某个专门的数据盘。注意,最大值的设置要小于所选磁盘的剩余空间,至少留出 5G 以上余量,这是硬底线。
4. 完整实操:一步步配置并验证效果
4.1 开始配置:绕过自动管理,自定义页面文件
先打开系统属性里的虚拟内存设置界面,和前面“查看当前大小”进去的路径一样。到了虚拟内存设置窗口后,第一件事就是取消勾选“自动管理所有驱动器的分页文件大小”。
然后选中 C 盘,选择“无分页文件”,点旁边的“设置”按钮。系统会警告你“C 盘不包含分页文件”,这没关系,点“是”确认。这一步的目的不是彻底关闭分页功能,而是让大型页面文件不占用系统盘空间。
接下来选中你想要放置页面文件的盘,比如 D 盘或 E 盘(数据盘、非系统盘)。选择“自定义大小”,填入“初始大小”和“最大值”。这里我拿一个 16G 内存、要做 Docker 和前端编译的机器举例子:初始大小填 8192MB,最大值填 24576MB。这意味着页面文件最少占用 8G,最多可扩展到 24G。
填完以后务必点一下旁边的“设置”按钮,这一步很多人会漏掉。不点“设置”直接点“确定”,你填的数字不会生效,这个坑我见过不少人踩。然后一路点“确定”回到桌面,系统会提示“必须重新启动计算机才能应用这些更改”,先别急着重启,确认一下 C 盘隐藏文件 pagefile.sys 是否已经移除、D 盘是否生成了新的 pagefile.sys。
4.2 配置完成后的验证方法:怎么确认设置真的起作用了
重启后,先打开任务管理器的“性能”选项卡,切到“内存”,右下角看“已提交”部分的“提交限制”。如果刚才最大值填了 24576MB,物理内存是 16G(约 16384MB),那么提交限制大约会显示 40960MB 左右(16384 + 24576),这才说明页面文件上限真正生效了。
更严谨的方法是打开文件资源管理器,进入设置了页面文件的盘,勾选“隐藏的项目”,看看是否生成了名为 pagefile.sys 的文件,右键属性可以看到它的大小。初始设置为 8192MB 时,文件大概就是 8192MB(8G)左右。如果文件大小和预期差很多,说明系统可能还在做调整,等几分钟或者再重启一次再看看。
如果需要模拟高强度内存场景,可以用一个比较极端的方式验证:同时打开大量 Chrome 标签页,或者跑一个内存压力高的脚本。我自己常用的是打开 Android Studio 加模拟器,同时跑着一到两个 Docker 容器和 Node 服务器,再开着一堆文档页面,几十个进程一起跑,观察任务管理器的“已提交”指标是否稳定上行、系统有没有弹窗报错。只要“已提交”没有逼近“提交限制”,OOM 就不可能出现。
4.3 实际案例:编译项目触发 OOM,调整后恢复
去年年底帮朋友排查过一台 Win11 机器,配置是 16G 内存 + 512G SSD,现象是每次用 VS 编译 C++ 项目时,编到一半编译器就报“fatal error C1060: compiler is out of heap memory”,换了几个 VS 版本都没解决,几乎要重装系统了。
我过去一看,虚拟内存设置里赫然写着“无分页文件”——多半是某个优化软件干的。这个配置下,16G 物理内存被 VS 和一堆服务占满后,编译进程申请不到任何后备内存,立刻 OOM。虽然系统没蓝屏,但编译器直接崩溃,影响非常直接。
当时我给的方案就是上面这套:C 盘保持无分页文件,把页面文件放到剩余空间还比较充足的 D 盘,初始大小设 8192MB,最大值设 24576MB,重启后重新编译,问题消失,实测编译期间“已提交”最高到过 30G 以上,如果没有那 24G 的页面文件,这个编译过程根本没有足够地址空间跑完。朋友后来反馈说还顺手解决了之前偶尔蓝屏的问题,就是关联页面文件扩展失败的旧账。
这个案例很有代表性,很多人一遇到编译 OOM 就以为是 CPU 不够或者代码有 bug,实际上八成是因为虚拟内存限制太紧,或者页面文件被某些“优化软件”折腾没了。
5. 常见问题与排查技巧
5.1 pagefile.sys 占用大、无法删除,怎么办
页面文件被占用是无法直接删除的,因为系统正在使用它,你可以采用两种办法处理。第一种:通过上面的设置把对应盘改成“无分页文件”,然后重启,再回来就能删掉了。第二种:如果只是嫌占空间大,就把初始大小和最大值调小,重启后系统会自动收缩 pagefile.sys。
这里要注意,如果你的 C 盘 pagefile.sys 删不掉,多半是因为注册表里PagingFiles项还有残留,或者某些软件强制要求 C 盘存在页面文件。可以按 Win+R 输入regedit打开注册表编辑器,定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management,查看PagingFiles项的实际内容。不过一般情况下不建议手动改了,图形界面的设置在“设置”按钮确认后就很可靠。
还有个小技巧:如果你想知道当前页面文件具体在哪个文件、占用多少,可以用系统自带的wmic pagefile list /format:list命令,直接输出所有页面文件的路径和大小,比在磁盘里翻隐藏文件更快。
5.2 修改后提示“配置错误”或系统不生效,怎么排查
最常见的情况是填写了自定义大小,也点了“设置”,但重启后任务管理器里的“提交限制”没有变化,或者某个盘还是用的系统托管。排查方向有三步。
第一步,看其他盘是否残留了页面文件。如果你在设置窗口里给多个盘都分配了页面文件,系统会综合所有盘的上限作为最终“提交限制”。你只想让 D 盘放页面文件,那 C 盘、E 盘等必须都设为“无分页文件”,并且确认每个设置都点过“设置”按钮。
第二步,打开事件查看器,在“Windows 日志 - 系统”里过滤来源为“Kernel-Paging”的事件,能看到系统对页面文件的识别、扩展情况。如果发现“硬盘空间不足”之类的记录,往往就是磁盘剩余空间不够,导致页面文件无法扩展到指定最大值。
第三步,确认系统盘和数据盘的文件系统没有开启“压缩内容以节省磁盘空间”。右键盘符属性,取消勾选“压缩此驱动器以节省磁盘空间”,这个选项可能干扰页面文件的正常映射,在 Win11 上尤其要注意。
5.3 Docker、Elasticsearch、MySQL 等应用 OOM,到底要不要调虚拟内存
这个问题的答案很容易被带偏。比如 Docker Desktop 在 Windows 上默认给虚拟机分配一定量内存,容器内进程 OOM 通常是容器内存限制导致的。遇到这种情况,调整虚拟内存解决不了根本问题,正确做法是去 Docker Desktop 的设置里调大 WSL2 或 Hyper-V 虚拟机的内存上限,或者给单个容器加--memory参数。同样的,Elasticsearch 的 OOM 多半是 JVM 堆内存设置问题,要改 ES 的jvm.options;MySQL 的 OOM 往往和innodb_buffer_pool_size调太大有关。
但不要反过来忽略虚拟内存的影响。比如你用 Docker Desktop 跑多个容器,宿主机的 WSL2 进程本身会占用大量物理内存,当宿主机物理内存耗尽又无法扩展页面文件时,整个 Docker 服务可能被系统直接终止,表现就是容器全部退出,报“The container operating system has shut down”。这时候调整虚拟内存能解决一部分问题,因为它给宿主机内核和 VM 进程提供了安全垫。
所以我的建议是:应用内 OOM,优先查应用自己的限制;宿主机 OOM,再检查虚拟内存。从 JDK 17 的Native Memory Tracking、ES 的 dump 日志,到 Docker 容器的docker stats输出,都要先看业务侧数据,而不是一股脑去改 Windows 页面文件。
5.4 32GB、64GB 大内存机器,要不要关虚拟内存
这个问题几乎每个“32GB 内存电脑的虚拟内存怎么设置”的帖子下面都有人争论。说“32G 内存已经够用了,虚拟内存可以关掉”的,多半只考虑了桌面应用,但一旦你跑大型编译、机器学习推理、多个虚拟机、巨型数据库实例,任何单一内存配置都可能撞到天花板。
微软官方的说法是即使有大量物理内存,也不建议完全禁用页面文件,因为 Windows 内部有一些机制依赖它。我在几十台服务器和开发机上实测下来,48G 内存的机器如果同时跑多个 Docker 容器和 VS 编译,依然有可能把物理内存消耗到 70% 以上,这时一个小页面文件能兜底,完全禁用就是在赌博。
所以,大内存机器我的建议是:不要彻底关闭,可以设一个比较小的固定页面文件。比如物理内存 32G 的用户设初始和最大均为 2048MB,或者 4096MB,就够用了。真正的重点是内存监控与消耗大户管理,而不是页面文件的数字。
6. 写在最后:我的经验与建议
从最早在机械硬盘时代折腾虚拟内存的大小比例,到现在给新装机方案里顺手就加上页面文件配置,这条路走下来我最深的体会是:没有一套配置能适配所有人,但有一套完整的判断逻辑可以反复复用。
先说结论,再补充一个我强烈推荐的“最小可行配置”思路。如果你不知道自己该设多大,先按“物理内存的一半为初始值、物理内存的一倍为最大值”来设,把页面文件放在剩余空间充足的盘上,跑几天看事件查看器里有没有“Paging”相关警告,再看任务管理器里的提交限制和已提交的比例。如果比例长期低于 60%,说明页面文件配大了,可以往下调;如果接近 80% 甚至 90%,说明需要加大。这个方法不依赖任何第三方工具,纯看系统自身指标,基本两三轮调整就能找到最适合自己的值。
最后分享一个小忠告:千万不要迷信某些“一键优化”软件里的“关掉虚拟内存提升性能”选项。虚拟内存不是拖慢系统的元凶,拖慢系统的是物理内存不够还硬扛的程序。把页面文件放在一块健康、空间充足的 SSD 盘上,用固定大小避免频繁扩展,剩下的交给系统自己调度,绝大多数 OOM 问题都能从根上消掉。