前几天一个朋友在群里发了张截图:电脑配置是 32GB 内存,平时主要跑着 Docker Desktop、IDEA、Navicat,外加一个 Elasticsearch 单机实例,结果 Windows 突然弹出“系统内存不足”的警告,随后 IDEA 直接卡死。群里几乎异口同声给出了建议——把虚拟内存调大。这个场景我在这些年里见过太多次了。问题在于,很多人对"虚拟内存"的理解停留在"硬盘划一块地方当内存用"这个层面,于是要么照着网上教程随手设了个 16GB,要么干脆一不做二不休禁用掉。这两种做法,在特定场景下都可能把系统搞得更糟。这篇内容我想做的事很简单:把 Windows 虚拟内存涉及的底层机制讲清楚,把网上流传的误区一个个拆掉,再给出从诊断到配置、再到验证的完整路径。无论你是被 OOM 困扰的开发者,还是想把手头电脑性能压榨到极致的重度用户,这篇都值得花十分钟看完。
1. 分页文件不是"第二块内存":先把底层机制拆开看
1.1 虚拟地址空间到底是什么
要理解虚拟内存,必须先接受一个事实:你写代码时拿到的那个地址,从头到尾都不是真实的内存地址。现代操作系统(Windows、Linux、macOS 都一样)给每个进程分配了一个独立的虚拟地址空间。在 64 位系统上,这个空间理论上是 16EB(也就是 2 的 64 次方字节),但 Windows 实际只实现到 128TB 用户态可用。这就是一个巨大的"虚拟货架",进程只管往这个货架上放东西、贴标签,至于货架上的某个格子最终对应到哪根物理内存条、还是对应到磁盘上的某个文件、又或者根本就是个空壳,由操作系统在幕后完成映射。
这个抽象层解决了两个核心问题:第一,内存隔离——进程 A 完全看不到进程 B 的地址空间,一个进程里出现野指针崩溃,不会直接把另一个进程的数据踩烂;第二,物理内存超卖——多个进程分配的虚拟地址空间总和可以远大于物理内存的容量,操作系统按需把真正用到的部分映射到物理页面上。打个比方,物理内存是仓库里真实存在的货架,虚拟地址空间是每个柜台手里的一本商品目录册。客户(CPU)来买东西时,售货员(MMU,内存管理单元)照着目录册查一下,这个商品实际放在哪个货架,然后去取。如果目录册登记了但货架上没有,就得让库管(操作系统内核)去库房(磁盘)调货。
1.2 分页文件在里面的真实角色
那分页文件(pagefile.sys)在整个机制里的位置就很清楚了:它是虚拟地址空间在磁盘上的后备存储。当物理内存吃不消时,操作系统会把一部分暂时用不上的内存页"腾"到磁盘上,腾出来的物理页面让给正在被频繁访问的数据。这个过程叫"换出"(page out);当 CPU 再次访问那些被换出的页面时,再把它从磁盘读回物理内存,叫"换入"(page in)。在 Windows 的性能计数器里,对应术语叫"硬错误"(Hard Fault)——注意这和程序崩溃时的"硬错误"完全是两码事,这里指的是页面不在物理内存、必须访问磁盘才能解决的缺页中断。判断内存压力的关键指标之一,就是硬错误的发生频率。
很多人有个误解,以为虚拟内存等于物理内存不够时的"救命稻草",只有内存占满才启用。这个理解是错的。分页机制是持续运转的,哪怕物理内存还有一大半空闲,Windows 也会把一些很久没被访问的页面换出,以维持足够多的"空闲物理页面"池子。这个池子有多重要?当程序突然需要大量连续物理页(比如启动大型应用、分配大数组)时,如果空闲页池太小,操作系统就得临时去找哪些页面可以换出、然后执行换出操作,这个连锁动作会直接表现为卡顿。所以你经常会看到一种现象:任务管理器里内存占用才 50%,但某个大程序启动时还是卡了好几秒,很可能就是因为空闲页池不够深,现换现用。
1.3 物理内存很大,为什么还需要分页文件
这是被问得最多的问题:"我 32GB 内存,平时都用不到一半,虚拟内存还有啥意义?直接禁用不行吗?"答案是不行,而且有个非常实际的技术原因——内核态的内存需求不会因为你物理内存大就消失。Windows 内核在做驱动校验、生成崩溃转储(蓝屏时的 dump 文件)时,默认都要依赖分页文件。你如果直接把分页文件禁掉,系统虽然能跑,但一旦发生内核模式崩溃,就没有足够空间写完整转储,之后排查问题会非常被动。另外,很多第三方软件的行为是"检查分页文件是否存在"来决定是否启用某些功能,而不是看物理内存总量。Adobe 全家桶就是典型例子,有些版本如果检测不到分页文件,会拒绝运行某些渲染任务,或者直接崩给你看。
所以结论很明确:分页文件不能禁用,但它的大小和位置,确实值得手动干预。这也是本篇文章从原理落到实操的切入点。
2. 关于虚拟内存的几个"经典说法",哪些该直接扔掉
2.1 "虚拟内存设置得越大越好":大得没边会付出隐藏代价
很多人设置虚拟内存时有一种心态:既然怕不够用,那就往死里调。4GB 物理内存设 16GB,16GB 内存也设 16GB,32GB 内存直接设到 64GB。这个思路有两个问题。第一个问题是磁盘空间占用。分页文件在默认配置下是动态伸缩的,一个设置不当的最大值上限,意味着在极端情况下它真的会吃满你预留的全部空间。系统盘一旦被 pagefile.sys 塞满,你遇到的就不仅仅是内存问题,而是一连串连锁故障:Windows Update 装不上、临时文件写不了、某些数据库直接拒绝启动。
第二个问题容易被忽略——大分页文件会影响休眠和快速启动的行为。Windows 的休眠模式(hiberfil.sys)和快速启动依赖在关机时把内核会话写入磁盘,如果分页文件太大,这部分 IO 耗时会变长。在某些配置下,用户会感觉到"点了关机后电源灯很久才灭",这就是在写缓存。所以虚拟内存有一个"合理区间",超出这个区间不会带来额外收益,只会白白消耗磁盘资源和 IO 带宽。
2.2 "放在 D 盘比 C 盘快":这个结论是有前提的
网上几乎每个教程都在说"分页文件不要放 C 盘,放到非系统盘",这话只对了一半。微软官方文档里的说法是:分页文件放在系统盘(C 盘),Windows 才能正常创建内核崩溃转储。如果你把分页文件完全移到 D 盘,系统蓝屏时是找不到足够空间去写 dump 文件的。
那"放 D 盘更快"的理论依据是什么呢?有些人用机械硬盘(HDD),系统盘和应用都在 C 盘,IO 已经相当繁忙,把分页文件放到一块空闲的 D 盘,确实能把页面换入换出的 IO 压力分摊到另一块物理磁盘上,这是合理的。但如果你用的是单块 SSD,把分页文件从 C 盘挪到 D 盘完全是多此一举,因为物理磁盘就一块,分区只是逻辑上的划分,IO 负载并没有变化,反而可能因为跨越分区边界带来额外的碎片问题。所以我的建议是:单 SSD 用户默认保持 C 盘;双硬盘用户(SSD 做系统、HDD 做数据)优先考虑在 SSD 上保留至少一个"由系统管理"的分页文件作为兜底,然后把另一个分页文件放到 HDD 上作为补充。游戏加载地图、开发工具读取缓存这类大量随机读场景,分页文件在 SSD 上的体验会好非常多。
2.3 "SSD 会被分页文件写坏":损耗话题下的账本算术
SSD 寿命恐惧症是个经久不衰的话题,每次提到分页文件就有人说"伤硬盘"。咱们认真算笔账:一个主流 512GB TLC SSD,官方耐久度标称通常在 300 TBW(总写入字节数)左右。假设你的虚拟内存设置得很激进,每天产生 50GB 的页面写入流量——这是非常夸张的场景了,日常生活根本达不到——那么一年写入量大约 18TB,这块 SSD 至少能扛 16 年。更何况,分页文件的实际写入量远没有想象中那么大,Windows 只会换出那些被修改过的"脏页",纯读取的映射页(比如内存映射文件)被换出后是可以直接从源文件重新加载的,写盘根本不会发生。
真正伤 SSD 的操作往往不是分页文件,而是有些人为了"加速"去禁用 Windows Search、关掉 Defrag 计划任务、或者停用 Prefetch——这些骚操作带来的收益微乎其微,反而让后台行为更不可预测。SSD 就是拿来读写的消耗品,别把它供着。
2.4 "32GB 内存就不需要虚拟内存了":内存碎片化了解一下
内存碎片化是站在"物理内存够大所以不需要分页文件"这一派的对立面。设想一个场景:你的系统里常年跑着十几个 Chrome 标签页、两个 IDEA 窗口、一个 SQL Server,然后你打开 Word 想处理个文档。此时物理内存总量可能还有十几个 GB 的空闲,但问题是这些空闲内存是碎片化的——分布在不同进程的保留区间之间,无法直接提供给需要连续大块物理内存的操作。这个场景 Windows 几乎不会主动报内存不足,但某些应用(比如老旧的 32 位设计软件、某些控制软件)在申请大块连续内存时就是会失败。分页文件存在时,系统可以把一些低优先级进程的已修改页面换出到磁盘,强行"压缩"出满足条件的物理页块,从而避免这次申请失败。
还有一个更硬核的技术点:Windows 的内存压缩(Memory Compression)与分页文件是协同关系,不是替代关系。从 1809 版本开始,Windows 会把很多压缩后的页面存放在内存中的"压缩存储区",而不是直接写盘。这个机制降低了分页文件的读写频率,但压缩存储区本身是有限的,它更像是一层缓冲,最终超压的部分仍然要落到 pagefile 里。物理内存再大,也扛不住某些进程无上限的内存泄漏。
3. 动手配置之前:先判断你的"内存不足"是哪一种
3.1 用性能监视器看内存压力,而不是只看任务管理器
任务管理器里的"内存使用"百分比只是一个非常粗糙的即时快照,它看不到内存压力的动态趋势。判断系统是否真的处于内存饥饿状态,建议打开 Windows 自带的性能监视器(perfmon),加入三组计数器观察:
| 计数器 | 合理范围 | 压力信号 |
|---|---|---|
| \Memory\Available MBytes | 长期大于物理内存的 20% | 持续低于 5% 且无回升 |
| \Memory\Pages/sec | 一般个位数到两位数 | 持续高于几百,说明频繁换页 |
| \Process\Working Set_Total | 与物理内存总量接近属正常 | 加上分页文件使用量后仍持续大涨 |
Pages/sec 这个指标要重点解释一下。它统计的是每秒硬错误加软错误的总次数,其中软错误(页面在内存中被重新分配)基本无害,真正需要关注的是硬错误。要单独看硬错误,可以在性能监视器里加 \Memory\Hard Faults/sec。如果硬错误长期稳定在个位数,说明内存调度非常健康;如果经常冲到几十、上百,就说明物理内存确实存在真实缺口,此时调大分页文件才算击中痛点。否则,就算你把它设成 100GB,瓶颈依旧存在。
3.2 事件查看器里的 OOM 蛛丝马迹
光凭任务管理器,你只能得知"当前内存紧张",却很难定位"谁在紧张"。Windows 在这件事上的记录其实非常完善。打开事件查看器(eventvwr.msc),展开"Windows 日志 - 系统",重点筛选来源为以下三类的记录:
- Resource-Exhaustion-Detector(事件 ID 2004):Windows 内存资源耗尽检测器发出的窗口内"内存不足"警告。它会给出触发时的进程名和内存提交量,同时指出哪个进程占用了最多已提交内存。
- Application Error(事件 ID 1000):应用崩溃记录,很多 OOM 导致的进程被杀会在这里留下异常代码 0xC0000005(非法访问)或 0xC00000FD(栈溢出)。
- Windows Error Reporting(事件 ID 1001):包含错误模块路径、异常偏移,对定位是否有第三方 DLL 干扰很有帮助。
把事件 ID 2004 的历史记录拉出来看,你会发现一个规律:绝大多数"内存不足"事件,主犯其实是那么一两个进程——Chrome 的渲染进程、Electron 应用、或者某个没有释放句柄的驱动。这比盲目调虚拟内存有意义得多,因为如果是某进程在泄漏,你调再大也一样会被吃掉。
3.3 区分"物理内存压力"和"虚拟地址空间耗尽"
这是很多开发者踩坑的重灾区。OOM(内存溢出)并非总是物理内存不足引起的。32 位进程默认只能看到 2GB 用户态虚拟地址空间(即使系统有 64GB 物理内存、32 位程序启用了 LAA 大地址支持也通常只有 4GB),所以一个 32 位进程哪怕物理内存还有很多富余,它自己的虚拟地址空间也会被耗尽,分配内存时直接抛 OOM。这事在旧版 Elasticsearch 上尤为常见——如果你用的是 32 位 JDK,或者没做对 jvm.options 的堆内存配置,明明机器内存很大,ES 却频繁报 OutOfMemoryError。
所以当你面对 OOM 时,先回答两个问题:第一,报错的是哪个进程?是操作系统层面的"内存不足"警告,还是某个特定应用抛出的 OOM 异常?第二,这个进程是 32 位还是 64 位?如果是 32 位进程,配置 Windows 虚拟内存完全帮不上忙,正确方向是换 64 位版本、给该进程开启 LAA、或者(在现代 Windows 上)依赖 WOW64 的地址空间重定位特性。如果是 64 位进程还在 OOM,那才轮到分页文件配置登场。
4. 手把手调整分页文件:图形界面与命令行两条路径
4.1 图形界面路径:三步完成的分页文件设置
现在进入实操环节。图形界面的路径是老生常谈,但我觉得还是值得按 2025 年的系统界面重新写一遍,因为 Windows 10 和 Windows 11 的设置菜单迭代过好几轮,很多教程截图的入口已经找不到了:
- 按下 Win + R,输入 sysdm.cpl 并回车,切换到"高级"选项卡。
- 在"性能"区域点击"设置",再次切换到"高级"选项卡,找到"虚拟内存"点击"更改"。
- 取消勾选"自动管理所有驱动器的分页文件大小"。
- 如果你的物理内存比较大(16GB 以上),可以先把"自定义大小"设到推荐的区间(下文会细说),或者保持"系统管理的大小"什么事都不做。
- 点击"设置"保存,重启系统。
这里有个细节:每一次修改分页文件后,Windows 都会要求你重启才能完全生效。因为页面调度机制在系统会话开始时就初始化好了,运行中途动态调整大小虽然能生效,但涉及到分页文件扩展和收缩的安全边界调整,某些内核组件(如崩溃转储)只有当分页文件在启动阶段就位时,才具备完整功能。所以我建议,但凡改完分页文件配置,计划一个重启窗口,别图省事。
4.2 不同内存容量下的推荐参数区间
"设置多大合适"没有绝对答案,但结合微软官方建议和多年实践,我整理了一个可以直接照抄的参考表:
| 物理内存 | 分页文件初始大小 | 分页文件最大大小 | 适用场景 |
|---|---|---|---|
| 4GB 及以下 | 物理内存的 1.5 倍(即 6144MB) | 物理内存的 3 倍(即 12288MB) | 老机器、低压上网本 |
| 8GB | 8192MB | 12288MB | 办公、轻度开发 |
| 16GB | 8192MB | 16384MB | 日常开发、虚拟机轻度使用 |
| 32GB | 4096MB | 12288MB | 重度开发、多虚拟机 |
| 64GB 及以上 | 4096MB | 8192MB | 工作站、视频渲染、大型编译 |
注意看,这个表和很多教程不一样的地方是:内存越大,初始大小和最大大小反而是下降趋势。原因很简单,物理内存规模本身能覆盖大部分工作负载,分页文件更多是兜底和兼容性角色。32GB 内存的机器去设置 64GB 分页文件,纯粹是浪费磁盘空间。如果打开了内存转储需求、或者运行一些对内存提交量要求极高的应用(比如某些 EDA 软件),可以适当上调最大大小,但初始大小保持在 4GB 到 8GB 已经非常健康。
4.3 分页文件的"自定义大小"与"系统管理"到底怎么选
微软默认的设置是"自动管理所有驱动器的分页文件大小",它由系统根据物理内存、页面提交量、应用负载动态伸缩。这个默认值其实很优秀,微软在内存管理上积累的成果都在这套逻辑里。但为什么很多人还是喜欢手动指定?因为自动伸缩有个微小但真实存在的问题:当系统检测到内存压力、开始扩展分页文件时,这个"扩展动作"本身是发生在高负载时期的,会在本来已经很紧张的磁盘 IO 上再叠加一笔额外的分配开销,极端情况下可能出现"越卡越扩展、越扩展越卡"的恶性循环。
手动指定一个合适的固定大小可以消除这个扩展过程,让分页文件的物理占用从一开始就达到足够大,IO 行为也更稳定。这就是"自定义大小"的实际意义。不过请注意,自定义不等于"只设固定值"。如果你取"初始大小 8192MB、最大大小 8192MB",就是完全固定;如果"初始大小 4096MB、最大大小 12288MB",则是固定下限加动态扩展。在个人 PC 上我更推荐后者——没有高频 IO 争抢时用下限值省空间,真要吃紧了还能弹性扩展。
4.4 命令行配置:适合批量部署的 PowerShell 方案
如果你要给公司里几十台机器统一配置虚拟内存,图形界面的效率太低了。用 PowerShell 调用 WMI 可以脚本化完成:
# 以管理员身份运行 # 将所有分页文件设置重置为"由系统管理",再为 C 盘设置自定义大小 $computers = @("PC01", "PC02", "PC03") foreach ($computer in $computers) { Invoke-Command -ComputerName $computer -ScriptBlock { # 取消自动管理 $sys = Get-WmiObject Win32_ComputerSystem -EnableAllPrivileges $sys.AutomaticManagedPagefile = $false $sys.Put() | Out-Null # 删除所有现有分页文件,然后新建一个 C 盘的固定大小配置 $pagefiles = Get-WmiObject Win32_PageFileSetting foreach ($pf in $pagefiles) { $pf.Delete() | Out-Null } Set-WmiInstance -Class Win32_PageFileSetting -Arguments @{ Name = "C:\pagefile.sys" InitialSize = 8192 MaximumSize = 12288 } | Out-Null # 立即尝试刷新,无需等待重启即可看到部分参数更新 Write-Output "$env:COMPUTERNAME pagefile updated, reboot required to fully apply" } }另一种写法是直接改注册表:
# HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management # PagingFiles 键值,格式:路径 初始大小 最大大小 # 例如:"C:\pagefile.sys 8192 12288" Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" ` -Name "PagingFiles" -Value "C:\pagefile.sys 8192 12288" -Type MultiString两种方法二选一即可。注册表方式更底层,WMI 方式更符合 Windows 管理规范。无论哪种,都别忘记在调用后重启机器并确认页面文件设置生效。
5. 开发与专业场景的虚拟内存专项配置
5.1 Elasticsearch 的 OOM 与虚拟内存配置边界
搜热词列表里有一批人是在折腾 Elasticsearch。ES 属于那种对内存极其敏感的开发中间件,但它报 OOM 时,调整 Windows 虚拟内存往往不是首选方案。原因在于 ES 基于 JVM 运行,JVM 的堆内存只受进程自己的 Xmx 参数控制,分页文件无法缓解 Java 堆的 OutOfMemoryError。如果 Xmx 给得太大,超过了物理内存能提供的真实空间,JVM 会发生 GC 抖动、频繁 Full GC、甚至整个进程被操作系统判"极刑"(OOM Killer 或者直接异常退出)。
ES 场景下,正确的虚拟内存相关操作是运行 bootstrap checks 时提示的max_map_count问题——在 Linux 上要调 vm.max_map_count,这是内核参数。但 Windows 上没有直接对应项,ES 的 bootstrap checks 里也没有针对 Windows 的 map count 检查。Windows 上跑 ES 真正容易出现的问题是mmap 文件映射的段映射数量限制,表现为启动时报max file descriptors [4096] for elasticsearch process is too low——这也不是分页文件能解决的。所以我的结论是:如果你的 Windows 上跑 ES 频繁 OOM,优先检查 JDK 位数(必须 64 位)、堆内存配置(建议不超过物理内存的 50%)、以及是否需要限制搜索线程和聚合桶数量;分页文件的调整可以做,但要放在最后顺位。
5.2 Docker Desktop / WSL2 的内存压力和 vmmem 进程
搜索引擎里还有一堆人在问"docker windows 内存不足"。Docker Desktop 在 Windows 上用 WSL2 后端运行时,默认会创建一个虚拟内存文件来模拟 Linux 的交换空间。这个虚拟磁盘文件(ext4.vhdx)会占用最多到 Docker Desktop 设置里分配的内存量。默认 Docker Desktop 会把 WSL2 总内存限制设为主机内存的 50%,但很多人在设置里改内存限制时,容易忽略一个硬约束:WSL2 的交换文件是独立的,它不依赖 Windows 的 pagefile。如果你给 WSL2 分配了 8GB 内存又分配了 2GB swap,这 10GB 理论上限和 Windows 分页文件没有半毛钱关系。
那为什么改 Windows 虚拟内存对 Docker 用户依然有意义?因为 WSL2 的 vmmem 进程在宿主机上就是一个进程,它的内存由 Windows 统一管理。当多个 WSL 发行版同时运行、Docker 容器数量增长时,vmmem 的物理内存占用会上升,这部分压力会传导到 Windows 的整体内存调度上。此时 Windows 分页文件的大小会影响系统能否优雅地扛过这个压力。我的建议是:如果你频繁使用 Docker Desktop,Windows 的分页文件至少保留 8GB 以上(无论是系统管理还是自定义),防止极端情况下 WSL2 与宿主机争抢内存导致系统僵死。同时把 Docker Desktop 的 Memory 限制设置在物理内存的 50% 以内,留出余量给宿主机自身和 IDE。
5.3 IDEA、Visual Studio、大型编译任务的内存分配
IDE 和编译器是另一个内存大户。IntelliJ IDEA 在代码索引、Gradle/Maven 构建时会创建大量内存映射和缓存对象,它的 JVM 堆内存默认值(通常 2GB 起步)不足以支撑大型工程,需要手动调整idea64.exe.vmoptions。这里有个关键的交互逻辑:JVM 堆的上限不能超过物理内存减去系统和 IDE 自身开销后的剩余量,否则就是给后续的 OOM 埋雷。而 Windows 分页文件在这里的作用是"缓冲池"——当一个大型编译任务瞬间申请了超出空闲物理内存的堆外内存时(比如 mmap 文件、JIT 编译器的代码缓存),分页文件能提供一个临时空间,让编译任务不至于被直接杀掉。
Visual Studio 的 MSBuild 并发编译也类似。C++ 项目的并行编译会在短时间内分配大量堆内存。如果你经常做大型 C++ 编译,建议把 Windows 分页文件设在 16GB 到 32GB 之间,并且确保所在分区剩余空间充裕。否则你可能会遇到编译进行到一半突然报fatal error C1083或D8021这类看似"文件打不开"、实则内存不足以支撑编译器的错误。
5.4 GPU 共享内存与"显存不足"的边界
热词里还有不少人在搜"gpu 虚拟内存"——这个和 Windows 的 pagefile.sys 有一点点关系,但机制完全不同。当显存(VRAM)不足时,NVIDIA 和 AMD 驱动会使用"共享 GPU 内存"机制,从系统物理内存中划出一部分作为显存的溢出区域。而这部分"共享 GPU 内存"的容量,实际上受两个因素限制:驱动设定的最大值(通常等于物理内存的一半)以及 Windows 分页文件的剩余空间。当物理内存本身也被占满、分页文件又不够大时,某些图形应用(比如本地跑 Stable Diffusion、视频渲染)就会报CUDA out of memory或DXGI_ERROR_DEVICE_REMOVED。
这里有一个实际的调优路径:如果你的工作负载需要频繁使用 GPU 大显存,把 Windows 分页文件设置在系统盘,并留出至少物理内存 25% 的空间,会给驱动的"共享内存"能力留出余量。别把分页文件完全禁用,否则某些驱动函数调用会直接失败。不过也要清醒一点:共享 GPU 内存的性能远不如真正的显存,它只是兜底方案。如果你的工作负载稳定超过显存容量,正确的做法是换更大显存的显卡或降低分辨率/模型规模,而不是靠虚拟内存硬扛。
6. 配置之后还要会验证:别让调整变成"自我安慰"
6.1 确认分页文件真正生效的两种方法
一般人在"设置"界面看到路径和大小数字,就以为配置好了。但 Windows 存在一种"设置保存了、系统没采用"的情况,尤其在多块硬盘、权限异常、或者被组策略锁定的环境里。所以配置完成后要验证。
第一种方式最简单:任务管理器 - 性能 - 内存,看"已提交"区域,或者用系统信息面板分页文件大小。但这个只能看到汇总。更精确的方式是用 PowerShell 查询:
Get-CimInstance Win32_PageFileUsage | Select-Object Name, AllocatedBaseSize, CurrentUsage, PeakUsage如果AllocatedBaseSize显示的值和你设置的初始大小一致,说明系统已采用;如果CurrentUsage持续逼近AllocatedBaseSize,说明分页文件可能不够大,需要加大。另外用Get-CimInstance Win32_PageFileSetting可以看到配置的初始大小和最大大小,两相对比就能确认配置是否完整生效。
还要注意一种特殊状态:当你的初始大小和最大大小设置相同(完全固定),系统会一次性分配完整文件,磁盘上立刻出现对应大小的 pagefile.sys;如果设置了不同的初始和最大大小,初始阶段 pagefile.sys 是"稀疏文件",占用磁盘空间小于最大值,这是正常的,不是配置失败。
6.2 调完虚拟内存还是频繁 OOM:五个排查方向
这是最让人沮丧的情况——明明把分页文件从 4GB 调到了 32GB,问题依旧。如果发生这种状况,请按顺序排查以下五个方向,而不是继续加大分页文件:
第一,是不是 32 位进程的虚拟地址空间耗尽。用任务管理器 - 详细信息,添加"程序类型"列,把出问题的进程标为"32 位"的话,优先换 64 位版本或启用大内存地址。这一步和 Windows 全局虚拟内存设置无关。
第二,是不是有内核态内存泄漏。有些第三方驱动(尤其是老版本网卡驱动、杀毒软件的过滤驱动、虚拟化平台代理)会在内核池中持续泄漏非分页内存。用 PoolMon(Windows 驱动工具包自带)能看到非分页池的字节数趋势。正常空闲状态下这个数值应该稳定,持续上涨说明有泄漏。
第三,是不是提交量本身超标。任务管理器 - 性能 - 内存,看"提交"部分的峰值。如果提交峰值已经超过物理内存 + 分页文件的上限,说明系统设计的"已提交内存"空间不足。这种情况需要看是否有某进程创建了巨大的虚拟内存保留区(比如早期 Firefox 的 bug),而不只是会话内存不足。
第四,是不是存储 IO 成了瓶颈。分页文件扩容了,但换页速度取决于磁盘速度。如果分页文件所在磁盘随机读写速度非常慢(比如一块 5400 转机械盘),系统可能依然表现为"卡死式 OOM"——因为页面换入的速度赶不上 CPU 的请求。把分页文件挪到 SSD,比一味增加大小有效得多。
第五,是不是应用自身的 OOM 与系统无关。Elasticsearch、Java 应用、Node.js 的 OOM 是进程内堆内存耗尽,Windows 分页文件再大也救不了。查 JVM 的 -Xmx、Node 的 --max-old-space-size,方向完全不同。
6.3 如何把配置迁移到新电脑/重装系统之后
最后分享个实用技巧:每次配置好分页文件后,把关键信息保存成一个文本或注册表导出,方便重装系统后快速恢复。我自己的做法是写一个一键脚本:
# 保存当前配置 reg export "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" C:\Backup\mem_mgmt.reg # 重装后恢复 reg import C:\Backup\mem_mgmt.reg但注意,这个注册表键里还包括了 ClearPageFileAtShutdown、DisablePagingExecutive 等多种设置,如果只是改分页文件,手写一个配置脚本更干净。把第 4.4 节里的 PowerShell 脚本存成 ps1 文件,重装后右键"使用 PowerShell 运行",30 秒就能恢复一套完整配置。把分页文件设置固化成"基础设施清单"的一部分,比每次都在图形界面里翻来翻去省事得多。
回到文章开头那个朋友。他真正的问题不是虚拟内存不够,而是 Docker Desktop 的 WSL2 内存限制没有配置、IDEA 堆给到了 8GB、ES 堆又给了 6GB——三座大山叠加,32GB 物理内存根本扛不住。我让他把分页文件固定到 8GB~16GB、把 WSL2 内存上限调到 12GB、IDEA 堆降到 4GB,之后重启再也没出现过内存不足。这说明一个很朴素的道理:虚拟内存是系统资源调度的最后一道缓冲,而不应该成为你忽视真实内存分配现状的借口。把分页文件配置到健康区间,再把那些"内存大户"的设置各自理顺,OOM 才能真正远离你。希望这篇从原理到实操的梳理,能帮你一次性把这些概念捋顺。