ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Windows虚拟内存与页面文件配置指南:从OOM到内存调优实践

Windows虚拟内存与页面文件配置指南:从OOM到内存调优实践 1. 从“内存不足”说起OOM 到底是怎么发生的1.1 一次真实的报错现场先聊一个我前几天在技术群里看到的场景。一个做后端开发的朋友机器是 32GB 内存的台式机跑着 IntelliJ IDEA、两个 Docker 容器、若干 Node 服务结果在启动 Elasticsearch 的时候直接弹了“内存不足无法完成操作”接着 Java 进程报出java.lang.OutOfMemoryError: unable to create new native thread。他当时的第一反应是“内存条不够了得加内存”但打开任务管理器一看物理内存才用了 70% 左右磁盘还空着几百 GB。这个案例很有代表性。很多人一看到 OOMOut Of Memory就条件反射地认为是物理内存买小了实际上在 Windows 平台上OOM 的触发原因往往不只是物理内存一个维度。它可能是进程地址空间耗尽、可能是页面文件设置过小、可能是系统提交内存上限Commit Limit被打穿甚至可能是某个驱动或者程序疯狂请求内存导致系统进入“内存压力”状态。你如果没搞清楚这些就盲目加内存条、关虚拟内存、或者乱调注册表问题大概率不仅不会解决还会带来新的不稳定因素。这篇文章我就想从 Windows 虚拟内存的底层原理聊起把页面文件pagefile.sys、提交内存、OOM 之间的关系讲明白然后给出从 8GB 到 32GB 内存机器上可复现的配置实操步骤。不管你是在自己电脑上跑开发环境还是给公司服务器调优只要你曾被“内存不足”这四个字困扰过这篇文章就是给你写的。1.2 虚拟内存不是“补丁”而是内存管理的基础设施要理解 Windows 的虚拟内存得先接受一个事实Windows 的内存管理从来都是“虚拟地址空间 物理内存 页面文件”三者协作的结果。32 位程序时代每个进程默认只有 2GB 的用户态地址空间物理内存再大单个进程也只能用这么多到了 64 位时代地址空间上限大到几乎不用关心但物理内存依然是稀缺资源所以操作系统必须有一套机制把暂时用不到的内存数据挪到磁盘上腾出物理内存给正在活跃的程序用。这套机制就是虚拟内存的核心逻辑。它不是把硬盘当内存来“救急”那么简单而是操作系统内存调度的一部分。Windows 会把进程使用的内存页分成两类能被物理内存装下的活跃页和暂时不需要常驻物理内存的非活跃页。当物理内存吃紧时内存管理器通过“工作集修剪”把非活跃页写入页面文件 pagefile.sys当程序再次访问这些页时再从磁盘读回物理内存。这个换入换出的过程对应用层是透明的但性能代价很大——SSD 的随机读写延迟是纳秒级内存延迟的上百万倍。所以你可以把虚拟内存理解成一个“溢洪道”。平时水没漫过坝顶溢洪道没有任何存在感但一旦遇到突发洪峰溢洪道决定了你是淹掉下游城市还是只是损失一部分农田。Windows 的默认配置其实已经在用这套逻辑只是很多人在遇到 OOM 的时候并不知道去哪里看、怎么调。1.3 OOM 的两大类原因物理内存真的不够还是设置出了问题我排查过不少 OOM 问题总结下来 Windows 平台的“内存不足”大致可以归成两类。第一类是物理内存真的不够。这种情况常见于开了几十个 Chrome 标签页、后台挂着虚拟机、再用 IDE 打开一个大项目。机器物理内存长期处于 95% 以上的占用系统不得不疯狂做页面换入换出最终某个程序申请内存失败弹窗报错。这类场景的解法确实是加内存或者减少同时运行的程序数量。第二类是页面文件或提交内存设置不当导致的“假性内存不足”。Windows 在分配内存时并不是等到你真的用完物理内存才开始报错而是根据“提交内存上限”来判断。提交内存上限约等于“物理内存 页面文件大小”。比如物理内存 16GB页面文件 4GB那么系统允许所有进程累计提交的内存上限大约是 20GB。如果一个程序尝试通过VirtualAlloc或者malloc申请内存时系统发现当前已提交内存加上这次申请会超过上限就会直接拒绝分配哪怕物理内存还有不少空闲——因为系统要保证每个已提交的页面在将来被访问时都有地方放要么物理内存要么磁盘。这就是为什么你明明看到任务管理器里内存只用了 60%但程序就是报内存不足。搞清楚这个机制你就会明白为什么有时候单纯加内存条没用为什么有人把页面文件关掉之后反而频繁崩溃为什么服务器上跑 Java 程序明明堆内存设得很低却还是 OOM。接下来的内容我会一个个拆开讲。2. 页面文件的核心参数与 Windows 的默认策略2.1 pagefile.sys 到底是什么它和“虚拟内存”是什么关系在 Windows 里页面文件就是磁盘根目录下的pagefile.sys默认在 C 盘。你打开“文件夹选项”勾选“显示隐藏的系统文件”才能在资源管理器里看到它。它的大小和作用就是我们前面说的“溢洪道”物理内存不足时内存管理器把不常用的页面写进去程序启动时如果申请了大量内存系统也靠它来撑住提交上限。这里要澄清一个误区很多人把“虚拟内存”等同于“页面文件”其实 Windows 里的“虚拟内存”严格来说是整个虚拟地址空间机制页面文件只是它落到磁盘上的那一部分。但在日常交流中说“调整虚拟内存”基本就是指调整页面文件大小所以这篇博客里我也会沿用这个说法。pagefile.sys有几个关键属性初始大小、最大值、系统管理的大小以及“无分页文件”。其中初始大小决定了页面文件一开始占据的磁盘空间最大值是页面文件允许自动增长到的上限。如果你把两个值设成一样大就相当于固定大小的页面文件好处是避免系统频繁调整文件大小坏处是不够灵活。如果你选了“系统管理”Windows 会根据当前内存压力、历史峰值和磁盘剩余空间自动调整这个模式对大多数人来说是最省心的但它不够“可控”而且页面文件在 C 盘会频繁伸缩产生碎片。2.2 Windows 的“自动管理”实际上在干什么Windows 默认开启“自动管理所有驱动器的分页文件大小”这个选项。很多人的电脑从买来到报废都没动过这个设置平时也没出问题于是觉得“虚拟内存根本不用管”。这个想法在物理内存宽裕、负载不高的场景下是对的但一旦你开始跑大型软件、多开虚拟机或者做编译默认策略就可能成为瓶颈。系统管理的页面文件大小并不是固定的它会在启动时根据物理内存容量设定一个初始值然后在运行过程中按需增长。比如一台 16GB 内存的机器系统托管的页面文件初始可能是 2GB 到 4GB如果某天你同时启动了 PostgreSQL、Redis、Chrome、微信、IDE提交内存压力变大页面文件就会自动膨胀到 8GB 甚至更多。这个过程是动态的好处是不会浪费磁盘空间坏处是增长过程中可能触发一次磁盘写入风暴而且页面文件所在的盘如果空间不足扩容会失败反而引发更复杂的问题。另一个容易被忽略的点是Windows 在记录内核崩溃转储蓝屏 dump、休眠文件hiberfil.sys时也会参考页面文件的配置。如果你为了省空间把页面文件整个禁用了遇到蓝屏的时候系统可能没有足够的空间写 dump排查问题就会变得非常被动。所以我不建议在常规机器上彻底禁用页面文件除非你非常清楚自己在做什么。2.3 为什么有人建议禁用虚拟内存但我不建议我在不少论坛上看到过“内存 32GB 以上可以禁用虚拟内存”的说法理由是“物理内存都这么大还要虚拟内存干嘛禁用了还能省几十 GB 硬盘空间”。这个说法有一定道理但是风险很大。第一Windows 不少系统组件和后台服务在初始化时会调用VirtualAlloc之类的 API按提交内存的方式预留内存。如果物理内存完全足够禁用页面文件确实能跑但一旦某个程序发生内存泄漏或者某个夜间后台任务比如 Windows Search 索引、Defender 扫描瞬间申请了大量内存你的系统没有页面文件兜底就会直接触发大面积分配失败表现出来就是应用程序闪退、服务崩溃甚至在驱动层面出问题导致蓝屏。第二关闭页面文件之后Windows 的内存管理器少了一个重要的“减压阀”。以前可以用“把不活跃页面写到磁盘”的方式来腾出物理内存现在必须把那些页面压缩驻留在物理内存里或者强行终止进程。这种策略在负载波动大的机器上容易让系统变得“粘滞”前台操作卡顿、窗口切换迟钝、输入延迟高。所以我的建议是不管内存多大都保留一个至少 1GB 到 4GB 的页面文件具体看内存容量和用途。这不是保守而是给系统留一条安全通道。2.4 关键参数解读初始大小、最大值、系统托管、无分页文件进入虚拟内存设置界面后文会详细演示操作步骤你会看到几个选项自定义大小需要填“初始大小”和“最大值”两个值。系统管理的大小由 Windows 自动决定。无分页文件彻底关闭该盘符的页面文件。这三个模式没有绝对的好坏取决于你的使用场景。自定义大小适合那些对系统行为有明确预期的人比如你确定自己的内存峰值占用就是 24GB、物理内存 16GB那页面文件设成 8GB 到 16GB 就够系统管理适合“不想折腾、也没遇到问题”的普通用户无分页文件一般只在某些特殊场景下使用比如为了调试系统性能、或者在有足够物理内存且完全由应用程序托管内存的专用服务器上。在自定义大小这组参数里初始大小和最大值之间通常会有一段差额。这个差额的意义在于允许系统按需扩展但同时它会带来“页面文件被反复扩展缩小的开销”。如果你把初始大小和最大值设成同一个数值页面文件从一开始就占满空间后续不再扩容反而在运行期更稳定。缺点是你得提前预估好需要多大空间设小了后面还得回来改。3. 虚拟内存配置实操从入门到可复现3.1 先看看你当前系统的虚拟内存状态在动手修改之前我建议你先看一眼当前状态免得调了半天连原始数据都不知道。打开“任务管理器 - 性能 - 内存”右下角会显示“已提交X/Y GB”。这里的 Y 就是当前系统的提交上限约等于物理内存加页面文件最大值。再看“正在使用、可用”的数字就能大致判断系统压力。想看更详细的页面文件信息可以按Win R输入perfmon /rel打开“可靠性监视器”或者用systeminfo命令行工具查看。打开管理员 PowerShell执行systeminfo | Select-String 虚拟内存或者Get-CimInstance -ClassName Win32_PageFileUsage后者会输出页面文件的当前分配、峰值使用和所在盘符。我一般会顺手记下“当前分配 (AllocatedBaseSize)”和“峰值使用 (PeakUsage)”两个数值后续调整大小就靠它们做参考。如果峰值使用已经接近甚至超过当前分配说明默认配置偏小了。另外如果你怀疑某个进程在疯狂申请内存可以在任务管理器里按“内存(活动的私有工作集)”排序看看哪些进程最吃内存。这一步能帮你判断到底是物理内存瓶颈还是某个程序泄漏。3.2 手动配置页面文件一步步来我以 Windows 11 为例演示Win10 的路径几乎一样完整的修改流程是这样的按Win S搜索“查看高级系统设置”打开“系统属性 - 高级”选项卡。在“性能”区域点击“设置”切到“高级”选项卡。在“虚拟内存”区域点击“更改”。取消勾选“自动管理所有驱动器的分页文件大小”。选中 C 盘或者你想放置页面文件的其他盘点选“自定义大小”。填入初始大小和最大值。点击“设置”然后一路“确定”最后重启系统让改动生效。这里有一个非常关键的细节如果你在“驱动器 [卷标]”列表里选中某个盘把虚拟内存改成“无分页文件”并点击“设置”系统会提示你“如果不创建分页文件某些程序可能无法正常运行”这是正常的警告不用慌。另外一个容易被忽略的点是“系统在 C 盘保留 crash dump 信息”。Windows 的蓝屏转储文件默认写到 C 盘而在很多系统上转储的配置要求 C 盘必须存在一个页面文件。如果你把 C 盘页面文件完全关了即便系统没有崩溃也可能在后续做内核转储分析时发现拿不到 dump。这就是我为什么建议至少保留一个小页面文件在 C 盘。3.3 不同内存容量的推荐配置参考不同物理内存容量下页面文件怎么设我给出一个我自己验证过、也推荐给不少朋友的基准值。注意这不是唯一答案而是针对“大多数人日常轻度开发”场景的稳妥方案。物理内存使用场景初始大小 (MB)最大值 (MB)备注8GB普通办公、轻度网页浏览40968192需要给系统留出扩展空间特别是多开浏览器16GB日常办公 轻度开发IDE 浏览器819216384可以根据运行负载上下浮动32GB开发环境、编译、容器、虚拟机819216384物理内存充裕页面文件提供兜底即可64GB及以上大型编译、服务端、多虚拟机40968192大多数场景下 4GB 到 8GB 就够除非做特定压测为什么 16GB 内存我最推荐 8GB 到 16GB因为在这个容量下你大概率会跑 IDE、浏览器、数据库这些内存大户系统的提交内存峰值往往在 20GB 到 30GB 之间。页面文件设成 16GB 能让提交上限到 32GB既能覆盖大多数峰值场景又不会占太多磁盘空间。如果设太小比如 4GB那么你开十几个 Chrome 标签页再编译一次前端项目就可能撞到提交上限。设太大也没必要因为真的到了页面文件要疯狂换入换出的地步性能已经很难受了大页面文件只是让崩溃来得晚一点而已。再补充一个针对小内存8GB机器的细节建议初始大小设成 4096MB 以上因为 Windows 在更新系统、运行 Defender 全盘扫描时会产生较高的页面文件占用。如果初始太小系统会反复扩容页面文件表现为磁盘占用和系统卡顿突然升高。宁可一开始多给一点空间也别让系统不停动态调整。3.4 SSD 硬盘上的虚拟内存设置技巧现在大家基本都是 SSD虚拟内存写在 SSD 上比机械硬盘快很多但这并不代表可以无脑把页面文件放大。SSD 的写入寿命和性能存在一个平衡问题。虽然现代 SSD 的寿命对日常写入来说绰绰有余但页面文件这种高频随机写入的负载确实会加速消耗写入量。我的建议是第一如果你有多块硬盘优先把页面文件放在读写延迟低、剩余空间充足的 SSD 上。机械硬盘HDD放页面文件并不是不行但在内存压力大的时候你会明显感觉到系统卡顿因为机械硬盘的随机 IOPS 太低了。第二避免把页面文件放在系统盘C 盘以外的外置硬盘或网络驱动器上。Windows 官方也不支持在移动硬盘和网络磁盘上放置页面文件因为它们的链路不稳定如果传输中断系统内存管理会直接出问题。第三如果你有两块 SSD可以考虑把页面文件放在非系统盘上。这样系统盘上的系统文件访问和页面文件访问不会互相争抢 IO 队列多少能减少一点卡顿。不过前提是那块盘空间充足、健康状态良好。第四很多人问“SSD 虚拟内存设置技巧是不是应该关掉”。我的答案很直接不要关但可以调整。物理内存大、很少出现内存压力的情况下把页面文件设成较小的固定值比如 4GB就够了。这样既保留了兜底能力又减少了无谓的页面文件写入。3.5 多磁盘场景页面文件放哪个盘最合适如果你是双硬盘用户比如一块 512GB 的 NVMe SSD 装系统和软件再加一块 2TB 的机械盘存资料页面文件放哪里先说结论放在 NVMe SSD 上最好是放在非系统盘的那个分区。放机械盘虽然省了 SSD 的写入但内存压力一来系统换页速度会慢到让人崩溃。放系统盘也能用只是系统盘同时承担了系统文件、应用程序、临时文件的读写压力会更大。如果你有两块 SSD那就更明确页面文件放数量小、分区独立的那块避免和系统日志、休眠文件抢空间。还有一个很多人不知道的细节Windows 允许在不同盘符上创建多个页面文件。系统在内存压力下会优先使用性能高的那个页面文件。所以我一般不在多个盘符都创建页面文件除非你有特殊需求比如必须保证某个盘不能有页面文件否则管理起来很麻烦。我之前给一台双盘机器配过C 盘放一个 4GB 固定页面文件为了 crash dumpD 盘另一块 NVMe放一个 16GB 的页面文件供大负载场景动态使用。跑起来还算稳系统自动会优先用 D 盘那个大的。4. 特定场景下的虚拟内存调优4.1 编译与开发场景NetBeans、Maven、Node.js、VSCode 为何容易报内存不足开发者在 Windows 上遇到“内存不足”的高频场景往往不是系统桌面弹窗而是构建工具直接报错。比如 NetBeans 编译大项目时提示“内存不足”Maven 构建到一半报java.lang.OutOfMemoryErrorNode.js 写脚本时进程崩溃IDEA 卡死。这些场景的共同特点是IDE 或构建工具本身需要很大的堆内存和本地内存而且启动时往往会一次性提交大量内存。先拿 Java 系举例子。Maven 默认跑在 JVM 里如果你没有设置MAVEN_OPTSJVM 的默认最大堆内存取决于机器物理内存。在 16GB 的机器上默认 MaxHeap 可能是物理内存的四分之一也就是 4GB 左右。但如果你在 IDEA 里同时跑多个 Maven 模块或者在 NetBeans 里开启了较多插件JVM 的元空间、代码缓存、线程栈这些非堆内存也会占用不少。此时如果页面文件设得小提交内存上限被卡住JVM 根本不管物理内存是否有富余直接抛unable to create new native thread或者java heap space。针对这种场景除了调大页面文件按前面推荐的 16GB 内存至少 8GB 页面文件我还建议同步调整构建工具本身的堆参数。比如 Maven 在MAVEN_OPTS里加-Xmx4gIDEA 在Help - Change Memory Settings里把堆调大。页面文件是兜底工具堆参数是主动控制上限两者结合才不容易翻车。Node.js 前端构建也有类似的坑。Vite、Webpack 这些工具在处理大型项目时内存占用很容易飙到 2GB 以上而 Node 默认的老生代堆上限一般在 2GB 到 4GB 之间。如果你在 Windows 上跑 CI 脚本的时候遇到Reached heap limit Allocation failed - JavaScript heap out of memory多半和 Node 堆设置有关。用NODE_OPTIONS--max-old-space-size4096可以撑大堆内存但前提依然是系统提交内存上限要够否则 Node 进程申请不到内存。vscode本身是 Electron 应用多开几个大型工作区、装了很多扩展时内存占用也很可观。如果系统页面文件大小不够VSCode 会表现为打开项目时卡死、扩展进程反复崩溃。这种情况先调整系统页面文件再考虑禁用不需要的扩展。4.2 容器与服务端中间件Docker、Elasticsearch、Kafka 的 OOM 内幕现在很多人在 Windows 上用 Docker Desktop 跑容器或者在 Windows 上直接启动 Elasticsearch、Kafka 这类 Java 中间件。它们的内存管理方式和普通桌面应用不同更容易触发 OOM。Docker Desktop 在 Windows 上实际上运行在一个轻量级虚拟机里。这个 VM 会从宿主机划走一定内存默认可能是内存容量的一半比如 32GB 机器默认给 Docker VM 8GB。如果你在容器里跑多个服务VM 内存不够就会出现容器被杀、服务报错。这种“虚拟机 容器”的双层内存模型让“内存不足”的原因变得复杂可能是宿主机物理内存不够可能是 Docker VM 的内存上限不够也可能是宿主机的页面文件太小导致提交内存不足。我遇到过一个案例是 Docker VM 占 12GB、IDE 占 6GB、浏览器占 4GB物理内存 32GB 看似够但页面文件才 2GB最终结果就是某个瞬间提交内存超过上限Docker Desktop 整个崩掉。解决办法分两步一是在 Docker Desktop 的 Settings - Resources 里手动分配内存一般不要超过物理内存的一半除非机器只有 Docker 一个主要负载二是把宿主机页面文件至少设成 8GB 以上给系统一个缓冲。Elasticsearch 是 Java 应用但它和普通 Java 程序不太一样。它默认会锁定部分内存给 JVM 堆外缓存mmap这个区域使用的是本地内存而不是堆。启动时报memory locking requested for elasticsearch process but memory is not locked或者max virtual memory areas vm.max_map_count [65530] is too low在 Linux 上常见Windows 上则更多表现为直接在启动阶段 OOM。Windows 下排查 Elasticsearch OOM我一般先看jvm.options里的-Xms和-Xmx是否合理比如 32GB 机器给 4GB 到 8GB再看bootstrap.memory_lock是否开启。如果机器页面文件太小ES 在把索引文件映射到内存时会直接失败。Kafka 的 OOM 也很典型。Kafka 的日志段索引和页缓存高度依赖操作系统内存。Windows 上跑 Kafka 时如果物理内存足够但提交内存上限被页面文件卡住broker 可能在处理大量消息时直接抛出OutOfMemoryError并停止服务。我建议在 Kafka 所在机器上把页面文件设大一些比如最大 16GB同时调一下 Kafka 的KAFKA_HEAP_OPTS不要把堆设得太大给操作系统页缓存留出空间。4.3 游戏与图形应用GPU 虚拟内存与显存不足“虚拟内存”在游戏圈还有一个特殊指代就是显卡的“共享 GPU 内存”。Windows 在任务管理器 - 性能 - GPU 里会显示“专用 GPU 内存”和“共享 GPU 内存”两部分。前者是物理显存后者是当显存不够时从系统内存借用的部分。这个“共享 GPU 内存”本质上也受系统内存和页面文件的影响。如果游戏报“显存不足”或者“显卡驱动已停止响应”有时候问题根本不在显卡而是系统内存或页面文件不够。因为显卡驱动要为每个游戏分配可用的显存资源如果显存不够会退到共享 GPU 内存而共享 GPU 内存的“最大值”通常是物理内存的一半左右。这个值并不是你在某个面板里直接调的而是 Windows 根据物理内存自动决定的但页面文件大小会影响驱动能否成功提交共享内存。所以遇到显存不足检查一下页面文件是否设置了合理大小也是一个有效的排查方向。另外游戏加载大场景、纹理流送texture streaming时如果系统页面文件太小可能出现“纹理加载不出来”“卡顿明显”“程序闪退”等问题。个人经验是游戏本建议页面文件至少 8GB尤其是 16GB 内存的机型。关掉虚拟内存玩大型 3A 我试过一个开放世界游戏能跑到 40GB 以上的总内存占用没页面文件真的顶不住。4.4 数据库与其他开发组件MySQL、Redis、Windows 子系统的内存取舍在 Windows 上安装 MySQL 或 Redis经常会看到报错信息其中一部分是它们自身配置问题另一部分是系统内存压力所致。MySQL 的 InnoDB 缓冲池innodb_buffer_pool_size默认值在安装版里可能是物理内存的 70% 左右这非常激进。如果你只有 16GB 内存装完 MySQL 默认配置可能直接把缓冲池吃掉 10GB 以上再加上操作系统和其他软件内存压力瞬间拉满。这时候不从配置层面调低缓冲池光靠加大页面文件只是治标不治本。我建议开发机上把innodb_buffer_pool_size设成 2GB 到 4GB给操作系统和其他程序留点空间。Redis 在 Windows 上虽然只是开发环境但如果开启了持久化执行 BGSAVE 时 Redis 会 fork 一个子进程内存占用翻倍COW 技术下不是严格翻倍但峰值会明显上涨。如果系统页面文件太小fork 会失败表现为 Redis 直接退出或者报Cant save in background: fork: Cannot allocate memory。这种情况要么调大页面文件要么在启动配置里调低maxmemory二选一。Windows 子系统WSL2也是个大户。WSL2 默认会使用宿主机内存的 50% 左右还会分配一定量的交换文件swap。如果你在 WSL2 里跑 Docker、Node、Python这些内存消耗全部算在宿主机头上。很多人发现 WSL2 用着用着 Windows 就“内存不足”就是因为没有在.wslconfig里限制 WSL2 的内存上限。解决办法是在C:\Users\用户名\.wslconfig写上[wsl2] memory8GB swap4GB重新启动 WSL 后生效。配合宿主机 8GB 以上的页面文件基本能避免“WSL2 把 Windows 拖垮”的尴尬局面。5. 常见问题与排查技巧实录5.1 “内存不足无法打开此网页”到底是谁的锅浏览器报“内存不足无法打开此网页”是一个被问了无数遍的问题。从 Chrome、Edge 到 360 浏览器这个弹窗的触发机制都差不多浏览器进程或渲染进程在申请内存时被系统拒绝。这既可能是物理内存太低也可能是页面文件太小更可能是某个标签页插件泄漏了内存。我处理过这样一个案例客户浏览器一开就报错打开任务管理器一看Chrome 有三十多个进程占用了 14GB 内存。物理内存 16GB页面文件被手动设成了 1GB这能不出问题吗。后来把页面文件调到 8GB再关掉一批不用的扩展问题就解决了。排查这类问题先按住Shift Esc打开浏览器自带任务管理器看看哪个标签页占用异常。如果某个标签页占了几个 GB先关掉它如果整体占用居高不下考虑是不是扩展太多或者硬件加速导致的 GPU 进程异常。最后再回到系统层确认页面文件大小和提交内存上限是否合理。5.2 修改虚拟内存后开机变慢、蓝屏这是怎么踩出来的坑在我自己折腾的过程中最惨烈的一次是把页面文件完全关闭然后重启直接蓝屏进不了系统。虽然当时我有备份但那种“连安全模式都进不去”的感觉真的很刺激。所以我要特别提醒修改虚拟内存后建议至少留一个页面文件在系统盘而且不要把所有分区的页面文件都设成“无分页文件”。还有一次我把页面文件的初始大小设成 0只填了最大值结果某些程序在启动时查询页面文件可用空间发现是 0直接报错。大家记住一个原则初始大小至少要给一个正数建议和最大值相同或者接近。设成 0 的后果是系统在运行初期没有任何页面文件兜底直到它自动扩展出空间这期间如果有内存峰值就可能出问题。另外修改完页面文件后一定要重启很多情况下不重启也能暂时工作但部分驱动和服务会在启动时读取页面文件配置不重启会导致配置未完全生效。5.3 页面文件碎片化这是一个“存在但不用太焦虑”的问题老一批 Windows 教程经常提到页面文件碎片化会影响性能建议用第三方工具整理。这个说法在机械硬盘时代确实有意义因为文件碎片会导致磁头反复寻道。但现在大家都是 SSD 了碎片化对随机读写的性能影响已经小了很多再加上 Windows 的Defrag.exe本身就支持对页面文件在开机时进行整理defrag /C /U的某些行为会在启动时做普通用户没必要专门去折腾。真正的性能杀手不是碎片化而是“页面文件所在盘剩余空间不足”。如果页面文件要扩容却撞到磁盘空间不足轻则扩展失败重则触发系统报错。所以让页面文件所在的盘保持至少 20GB 左右的可用空间比纠结碎片化有意义得多。5.4 如何用性能监视器和日志定位 OOM 根因排查 OOM 问题光靠“感觉”不够还是要看数据。Windows 自带几个工具足够定位大多数问题。第一个是“性能监视器”perfmon。运行perfmon后在监视工具 - 性能监视器里添加计数器我一般关注这几个Memory\Committed Bytes、Memory\Commit Limit、Memory\Available MBytes、Paging File(_Total)\% Usage。其中“Committed Bytes”如果持续逼近“Commit Limit”说明提交内存快打满了Available MBytes如果长期低于几百 MB说明物理内存非常紧张Paging File \% Usage如果长期接近 100%说明页面文件设小了。第二个是“资源监视器”resmon。运行resmon切到“内存”选项卡可以直观看到每个进程的“提交”大小、工作集大小和“可共享/专用”内存。如果某个进程的“提交”数值异常大那它就是 OOM 的主要推手。第三个是事件查看器。打开“事件查看器 - Windows 日志 - 系统”在筛选里找Event ID 2004资源不足警告、Event ID 2019服务器无法从系统非页面缓冲池分配内存、Event ID 2020服务器无法分配页面缓冲池。这些事件通常比弹窗更早出现能帮你定位到是哪个进程在吃内存。5.5 常用排查命令与配置速查表目的命令/操作说明查看页面文件状态Get-CimInstance Win32_PageFileUsage显示当前分配、峰值使用、所在盘符查看提交内存上限任务管理器 - 性能 - 内存 - 已提交括号里的第二个数是 Commit Limit查看系统内存事件事件查看器 - Windows 日志 - 系统关注 2004/2019/2020 事件查看进程内存占用resmon- 内存观察每个进程的“提交”和“工作集”查看磁盘剩余空间Get-PSDrive C页面文件所在盘至少留 20GB 空间修改页面文件系统属性 - 高级 - 性能 - 设置 - 高级 - 虚拟内存取消自动管理后才是自定义设置 Docker 内存上限Docker Desktop 设置 - Resources不超过物理内存一半为宜设置 WSL2 内存上限C:\Users\用户\.wslconfig写 memory 和 swap 后重启 WSL我把上面表格里的内容称为“OOM 排查七件套”。每次遇到问题的内存报错我会按这个顺序过一遍基本能在十分钟内定位到问题主因比自己瞎猜效率高很多。5.6 几个容易踩的“隐藏坑”除了前面提到的大问题还有一些细节我在长期使用中总结出来了单独列在这里有些电脑厂商会预装优化软件在后台帮你把虚拟内存改成“无分页文件”。如果你发现自己设置页面文件后重启又被改回去先看看是不是这类软件干的好事。修改页面文件大小后不要立即尝试用第三方工具“马上生效”的切换功能。Windows 在运行中释放旧页面文件需要时间强制操作可能导致文件锁定或数据异常。如果你开了“快速启动”默认开启重启后页面文件可能不会被完全重新初始化。遇到页面文件过大或异常时试试完全关机再开机而不是“重启”。页面文件大小和休眠文件有一定联动。如果你关闭了页面文件又启用了休眠hiberfil.sys可能还会保留在系统盘占不少空间。这时候需要在管理员 CMD 里执行powercfg /h off才能真正释放。6. 结尾一点个人经验做了这么多年系统调优和开发环境维护我越来越觉得“虚拟内存”像一个老派的管家平时你不会注意到它但它一直在后台默默管理着内存的进出。很多人在优化系统的时候喜欢“做减法”看到不认识的占用就关掉看到能关的功能就禁用似乎关掉的东西越多系统就越干净越快。但虚拟内存恰好是一个反例。它不是“多余的负担”而是 Windows 内存管理机制里一个不可替代的组件。我踩过最深的坑就是当年为了省硬盘空间把页面文件整个关掉结果第二天编译项目时直接蓝屏折腾了大半天才恢复。从那以后我给自己定了一条规矩任何情况下至少保留一个固定大小的页面文件哪怕只有 2GB。如果你现在正被“内存不足”或 OOM 困扰我的建议是别急着买新内存条先打开任务管理器看一下物理内存占用和提交内存上限再用resmon看看是哪个进程在吃内存。很多时候一个合理的页面文件设置就解决了大半问题。如果调整完虚拟内存之后还有类似问题再去考虑加物理内存或者优化具体应用的参数那时候的判断才是有依据的。
返回列表