十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Windows虚拟内存与页面文件配置指南:告别“内存不足”

Windows虚拟内存与页面文件配置指南:告别“内存不足” 1. 页面文件不是“内存不够时用的低级货”先把运行机制捋清楚1.1 数据从内存到磁盘的完整路径先说一个我最近处理的案例。朋友的机器明明装了 32GB 内存平时打开 Chrome、微信、Office 也没觉得卡但某天跑一个解压脚本时突然弹窗“您的内存不足”再往后连浏览器标签页都打开失败。我远程一看任务管理器里物理内存还剩 10 多 GB但底部“提交”数值已经顶到了上限。这种情况十有八九和虚拟内存配置有关而不是物理内存真的买小了。要理解这个问题先得把 Windows 虚拟内存的运作方式讲清楚。很多人把“虚拟内存”等同于“用硬盘当内存”甚至以为它是老古董。实际上 Windows 的内存管理是一个三层结构物理内存RAM、虚拟地址空间、页面文件pagefile.sys。每个 64 位进程都拥有理论上非常大的虚拟地址空间程序申请内存时Windows 的内存管理器先分配虚拟地址空间然后才按需映射到物理内存。当物理内存不够用或者某些“已修改”的内存页长期没被访问时内存管理器会把它们写进 pagefile.sys腾出物理内存给更活跃的数据用。等到进程再次访问这些页时再从页面文件读回内存这就是我们常说的“换页”或“缺页中断”。注意一个反直觉的点页面文件并不是“物理内存满了才用”。它参与的是 Windows 的“提交内存”commit charge记账体系。程序申请内存时系统先“记账”保证未来要用的时候有地方放这个额度等于物理内存大小加上页面文件的当前大小。也就是说页面文件存在本身就是给系统提供了一个“承诺空间”不只是临时避难所。你把它关了就相当于把这道防线整个拆掉了。1.2 “禁用页面文件”听起来很酷其实是在拆安全绳我在很多装机群里看到一种说法内存有 32GB 甚至 64GB页面文件直接禁用零写入零碎片系统更快。这个观点害人不浅。物理内存再大Windows 内核、驱动、各种服务和第三方软件也会产生很多“已修改”页。内存压缩机制可以缓解一部分压力但它也有代价而且并不能替代页面文件。禁用页面文件至少会带来三个问题。第一提交上限直接锁死在物理内存大小一旦同时开的进程多哪怕物理内存还有剩余新的大块内存分配也会失败报出让人摸不着头脑的“内存不足”。第二系统崩溃转储crash dump需要借助页面文件写入没有页面文件蓝屏后的 dump 抓不完整甚至抓不到蓝屏原因分析直接无从下手。第三某些老旧软件或特殊驱动会假定页面文件存在禁用后出现随机崩溃。我自己也踩过这个坑。以前给一台 64GB 内存的测试机禁用页面文件跑一个 Visual Studio 编译项目时频繁出现std::bad_alloc一开始怀疑是代码问题后来重开页面文件就好了。所以我的结论很明确页面文件可以小但不要禁。2. 配置前的现状摸底让数据告诉你缺什么2.1 两个命令先看页面文件现状经常有朋友问我“怎么看虚拟内存大小”大多数人的做法还是右键“此电脑”——属性——高级系统设置然后在“性能设置”里找。这条路没错但在排查问题时效率很低因为它只能看到配置值看不到当前使用率。我更习惯先跑命令用数据说话。最简单的是在命令提示符或 PowerShell 里执行wmic pagefile list /format:list输出会包含这样的字段AllocatedBaseSize8192 CurrentUsage2048 NameC:\pagefile.sys PeakUsage6144其中AllocatedBaseSize是当前分配的基础大小单位 MBCurrentUsage是此刻已使用的量PeakUsage是开机以来的峰值使用量。如果你看到PeakUsage经常接近甚至等于AllocatedBaseSize说明当前配置偏小系统一直在尝试扩展页面文件扩展的过程会产生额外 IO 和卡顿。PowerShell 环境下也可以用 CIM 查询信息更规整Get-CimInstance Win32_PageFileUsage | Select-Object Name, AllocatedBaseSize, CurrentUsage, PeakUsage还有一个更直观的方法是打开任务管理器切到“性能”选项卡选中“内存”看右下角的“提交”部分。格式通常是“18.1/63.9 GB”前面的 18.1 是当前系统所有进程提交的内存总量后面的 63.9 是当前提交上限。这个数据才是判断“够不够用”的第一参考比单纯看物理内存占用率准确得多。2.2 提交限制才是“内存不足”的真正红线很多人只看任务管理器第一页的“内存使用量”发现物理内存才用了 60%就觉得系统不应该报内存不足。这里容易忽略一个关键概念Windows 的内存压力并不完全由物理内存占用率决定而是由“提交限制”commit limit和“提交量”commit charge之间的关系决定。提交限制的计算大致是物理内存总量 所有页面文件当前可扩展到的最大容量。如果系统页面文件很小比如只有 4GB那么即使物理内存 32GB整个系统的提交上限也就大约 36GB。而浏览器、IDE、容器、虚拟机这类软件动辄申请几 GB 的虚拟内存空间叠加起来很容易逼近上限。一旦逼近新分配就会失败返回“内存不足”或直接触发应用 OOM。我见过最典型的场景是一台 16GB 内存的笔记本页面文件被设成了固定 2GB然后同时打开三个大型项目、几十个浏览器标签页、几个微信/钉钉进程提交量很快跑到 20GB 以上系统就开始疯狂报错。这时候物理内存可能还有 6GB 空闲但系统已经“无法承诺”新的内存分配了。所以排查内存问题的第一步永远是打开任务管理器看“提交”这一栏而不是只看内存占用率。2.3 用资源监视器找“内存杀手”如果提交量很高接下来要搞清楚是谁在消耗内存。任务管理器切到“进程”并按内存排序可以看个大概但要看得更细建议用系统自带的“资源监视器”。Windows 10/11 里直接在开始菜单搜索“资源监视器”打开切到“内存”选项卡可以看到每个进程的“工作集”和“可共享”、“专用”等内存分类还能看到“硬错误/秒”这个关键指标。“硬错误/秒”表示进程每秒需要从磁盘页面文件读回数据的次数。这个值长期偏高说明物理内存确实不够用系统正在频繁换页表现为操作卡顿、程序响应慢。注意这个词叫“错误”但并不是真正的故障而是缺页中断只是它一旦密集出现体验会非常差。如果某个进程的硬错误很高我可以先用 RAMMap微软 Sysinternals 工具看一下它到底占了什么类别的内存是私有数据、映射文件还是页表。很多“内存占用爆表”的假象来自映射文件Mapped File并没有真正吃多少物理内存重启进程后这些占用通常会释放。这个辨别能力对排查“Windows 内存不足但不知道谁导致的”非常有用。3. 配置策略多大、放哪、选哪种模式3.1 大小公式失效了按场景给建议老一代 Windows 教程喜欢用“物理内存 1.5 倍”或“最小值 1 倍、最大值 2 倍”这样的公式。这套说法在机械硬盘、小内存时代有一定道理但现在内存普遍 16GB 起步再用倍数公式往往会设置出过大的页面文件白白占掉 SSD 空间。我的习惯是先看用途再看峰值提交量最后定大小。下面给出我这些年实测下来比较稳的参考值单位是 GB物理内存日常办公 / 网页浏览重度开发 / 多容器虚拟机 / 大型渲染8GB8~1616~2416~3216GB8~1616~3224~4832GB8~1616~2432~6464GB及以上系统托管或 8~168~1616~32如果你是普通用户不确定怎么选最省事的方案其实是把选择权交还给 Windows勾选“自动管理所有驱动器的分页文件大小”。这个选项在绝大多数场景下表现不错Windows 会根据负载动态扩展页面文件不会像固定值那样要么太小要么浪费空间。需要手动设置的场景是C 盘空间紧张、需要抓取完整崩溃转储、或者你已经明显看到“提交”长期接近上限。如果你倾向于手动设置我建议的最小值是“当前峰值提交量 - 物理内存大小”再加一点余量。这个峰值可以从任务管理器或者性能监视器里读也可以直接看PeakUsage。说白了页面文件并不需要等于物理内存的某个倍数而是要覆盖你日常工作负载的“峰值缺口”。3.2 页面文件放在哪个盘不是随手选的页面文件默认放在系统盘 C 盘。很多人因为 C 盘空间不够想把页面文件移到 D 盘或 E 盘这个思路本身没问题但有个前提必须知道系统崩溃转储通常依赖系统盘上的页面文件。如果完全把页面文件从 C 盘移除蓝屏时 Windows 往往只能生成很小的 minidump或者干脆告诉你“没有足够磁盘空间写入转储”这会对事后分析造成很大麻烦。所以我的建议是如果你确定要把页面文件转移到其他盘至少在 C 盘保留一个较小的页面文件比如 2~8GB作为转储和系统底层操作的后备。剩下的容量可以放到你读写最快的 SSD 上。“放到哪个盘”还要看磁盘类型和接口。假如你有两块 NVMe SSD建议放到空闲的那块上避免和系统、程序抢 IO。如果是一块 SSD 一块机械硬盘页面文件一定放 SSD不要因为 SSD 容量小而委屈它放到机械盘。机械硬盘的随机读写延迟在换页密集时是灾难级的系统会卡到像死机一样。3.3 固定大小 vs 系统托管手动设置时Windows 会让你填“初始大小”和“最大值”。很多人直接填两个不同值这就会产生一个问题系统会在两个值之间动态伸缩伸缩过程中会产生页面文件碎片和额外的 IO 开销重负载下容易出现卡顿。在 SSD 时代我更推荐把“初始大小”和“最大值”设成相同值也就是所谓的固定大小。这样做的好处有三个页面文件从一开始就占满指定空间不会出现运行时扩容的毛刺文件连续分配减少碎片内存分配行为更可预测排查问题时少一个变量。缺点是要一次性占掉一块固定磁盘空间但现在的 SSD 动辄 512GB 起步拿出一二十 GB 换稳定性价比很高。如果你的机器内存非常大比如 64GB 以上且磁盘空间又紧张我会优先建议“系统托管”而不是强行固定一个巨大的页面文件。因为大内存场景下页面文件更多是兜底和账本作用平时根本用不到多少系统托管足够灵活也能在崩溃转储时自动扩容。4. 实操图形界面、命令行和注册表三条路4.1 图形界面设置日常最常用Windows 10/11 的图形设置路径其实不算复杂我操作时习惯直接用运行命令打开省去一层层点鼠标按Win R输入sysdm.cpl回车。在“系统属性”窗口切到“高级”选项卡点击“性能”区域的“设置”。在“性能选项”窗口里切到“高级”选项卡点击“虚拟内存”区域的“更改”。取消勾选“自动管理所有驱动器的分页文件大小”。选中你要设置的磁盘比如 C 盘。选择“自定义大小”填入初始大小和最大值单位是 MB。点击“设置”按钮让配置生效然后一路确定最后重启系统。这里最容易踩的坑是只填了数字忘了点“设置”按钮直接点确定结果配置根本没生效。还有就是在多个磁盘之间来回切换时必须确认选中的是你真正想改的那块盘别在 D 盘上配了半天最后发现 C 盘还是原来的值。如果把某个磁盘设为“无分页文件”Windows 会弹出警告提醒你这样做可能导致系统崩溃时无法写入调试信息。我的建议是主力的系统盘不要选“无分页文件”宁可用小一点比如 2048MB 起步。4.2 PowerShell 与 WMIC适合批量管理如果你管着多台 Windows 机器图形界面太慢了。用命令行和脚本可以批量查看和修改页面文件配置。查看当前页面文件使用情况wmic pagefile list /format:list查看当前页面文件配置Get-CimInstance Win32_PageFileSetting | Select-Object Name, InitialSize, MaximumSize关闭“自动托管”并设置固定大小需要管理员权限的 PowerShell。假设我想把 C 盘页面文件设为固定 16384MB# 关闭自动托管 $cs Get-CimInstance Win32_ComputerSystem Set-CimInstance -InputObject $cs -Property {AutomaticManagedPagefile $false} # 设置页面文件初始和最大都为 16384MB $pf Get-CimInstance Win32_PageFileSetting | Where-Object { $_.Name -eq C:\pagefile.sys } if ($pf) { Set-CimInstance -InputObject $pf -Property {InitialSize 16384; MaximumSize 16384} }注意Set-CimInstance的语法在不同 Windows 版本上略有差异如果你用的旧系统不识别也可以退回到WMIC命令。命令行设置完成后同样需要重启才能完全生效。对于批量管理上百台机器的场景我一般会把这段脚本封装成.ps1文件配合远程执行工具一把梭。4.3 注册表直改应急和桌面运维还有一个更底层的修改路径注册表。页面文件的核心配置存在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management右侧有一个多字符串值PagingFiles。每行格式类似C:\pagefile.sys 16384 16384其中C:\pagefile.sys是页面文件路径后面两个数字分别是初始大小和最大大小单位 MB。如果想配置成系统托管可以写成C:\pagefile.sys 0 0如果想禁用某个盘的页面文件就把对应行删掉。这个方式适合桌面运维或者系统不是图形界面的场合修改注册表前一定要先备份虽然改错不至于把系统搞坏但花了很长时间排查一个低级错误就不值当了。我个人实际工作中很少直接用注册表去配页面文件因为可读性太差多盘多文件时容易看花眼。除非是应急处理远程机器或者 Windows PE 环境里调整否则优先用图形界面或者 PowerShell。5. SSD 时代的性能陷阱与“伤硬盘”焦虑5.1 页面文件放 SSD到底会不会伤盘几乎每次聊到页面文件都有人问SSD 不是有写入寿命吗把页面文件放 SSD 不是加速消耗吗这个担心可以理解但实测下来基本不需要过度焦虑。现代 TLC/QLC SSD 的 TBW总写入字节数动辄几百 TB普通用户一天写几十 GB 已经很夸张了按这个速度用十年也未必能写满寿命。页面文件的核心问题是“频繁写入”而不是“写入总量”。如果系统经常把页面文件当交换区反复读写说明物理内存确实吃紧这时候真正要做的是加大物理内存或者优化内存占用而不是反过来因为担心伤 SSD 把页面文件挪走。换一块 SSD 的成本往往比你每天忍受卡顿低得多。当然有一个小技巧值得用把页面文件设置为固定大小可以避免系统反复扩展文件从而减少不必要的写入。另外如果系统有内存压缩Windows 会优先使用压缩内存页减少写入页面文件的频率所以也不必手动关闭内存压缩。5.2 动态扩展带来的毛刺比想象中更影响体验在机械硬盘时代页面文件动态扩展只是慢一点、磁盘碎片多一点。到了 SSD 时代动态扩展对日常体验的影响变小了但在特定场景下依然会带来可感知的卡顿。比如你在编译大型项目内存突然出现尖峰页面文件在 8GB 和 16GB 之间瞬间扩容这时你会发现整个系统有短暂停顿鼠标都变得黏滞。出现这种现象的原因有两个一是页面文件扩展时文件系统需要分配新的簇可能触发元数据更新二是如果磁盘剩余空间碎片化严重扩展区域不连续后续读写性能会打折。固定大小虽然无法完全避免碎片但至少把“扩展”这一步的偶发开销去掉了。所以我的习惯是只要磁盘空间够就优先固定大小如果空间确实紧张那就用系统托管但定期检查剩余空间别让它膨胀到把 C 盘塞满。另一个容易忽略的点是页面文件大小设定了固定值后磁盘的剩余空间会肉眼可见地减少误以为磁盘“用光了”。提前计划好空间分配比事后补救省心得多。6. 从“内存不足”到 OOM一套完整排查链路6.1 两种常见 OOM 形态“OOM”在不同语境下指的东西不太一样。在 Linux 世界里大家熟悉的 OOM Killer 会在内存耗尽时挑进程杀在 Windows 世界里很少看到系统主动杀进程更多是两种情况一是应用申请内存失败直接崩溃比如 Java 程序报OutOfMemoryError浏览器标签页瞬间全部消失二是系统弹窗提示“内存不足”然后窗口、服务开始陆续出问题。这两种情况虽然表现不同但底层通常都和“提交量接近提交上限”相关。32 位进程还有一个单独的坑虚拟地址空间只有 4GB即使系统内存再大单个 32 位程序也可能因为地址空间耗尽而 OOM这种时候调页面文件没用要换 64 位版本或开启大地址支持。不过现在绝大多数应用已经是 64 位最常遇到的还是系统整体提交压力过大。如果你在排查 OOM第一步千万别急着调参数先记录一下现象是某个特定应用崩溃还是整个系统开始报错崩溃之前你打开了哪些程序任务管理器里提交量有没有顶到上限这些信息比任何理论分析都管用。6.2 排查链路事件日志与提交压力我处理 Windows OOM 问题时的排查顺序基本固定这里整理成一个链路打开任务管理器看“性能 - 内存”里的“提交”数值。如果“提交”已经达到或逼近后面的上限说明问题就在系统整体提交空间上。打开事件查看器路径是“Windows 日志 - 系统”筛选来源为Resource-Exhaustion-Detector查找事件 ID2004。这个事件会明确告诉你“Windows 已检测到虚拟内存使用不足”并且包含当时的提交量、限制值和页面文件情况。这是最直接的官方诊断证据。打开资源监视器按“硬错误/秒”排序找出正在频繁换页的进程。用 RAMMap 查看进程的内存分类确认是私有数据占用大还是映射文件导致虚高。根据占用量判断是“物理内存真的不够”还是“页面文件设置太小”然后决定是加内存、调页面文件还是优化软件占用。如果已经发生应用崩溃Windows 的应用程序事件日志里可能有.dmp文件记录先用任务管理器或者 WinDbg 打开看看崩溃时进程的提交量峰值。没有 dump 也没关系事件 ID 2004 里的数据已经能说明大部分问题。6.3 WSL2、Docker、Java 服务带来的新变数这几年“内存不足”问题里WSL2 和 Docker Desktop 成了新的主角。Docker Desktop 在 Windows 上默认使用 WSL2 后端WSL2 会动态占用宿主机内存而且占用机制看上去很“贪婪”。很多人发现装了 Docker 之后Windows 的提交量节节攀升页面文件膨胀甚至出现容器 OOM。这种场景下往宿主机页面文件上堆不是长久之计更有效的办法是给 WSL2 设置内存上限。在用户目录下创建或修改.wslconfig文件[wsl2] memory8GB swap4GB然后打开终端执行wsl --shutdown再重新进入 WSL2配置就会生效。注意这里的swap是 WSL2 内部的交换文件和 Windows 的页面文件是两套体系。限定了 WSL2 的内存之后Windows 宿主机的提交压力会明显下降。Java 系服务Elasticsearch、Kafka、Redis 某些实现等是另一个常见 OOM 来源。我自己在 Windows 上跑 Elasticsearch 时遇到过系统内存充足但服务反复 OOM 的情况最后发现是堆内存配置和系统页面文件设置打架。JVM 的堆内存和 Windows 页面文件是两个层面但 JVM 申请的堆内存也会计入系统提交量如果同时跑多个 Java 服务提交量很容易超预期。建议在jvm.options里根据物理内存合理设置堆大小同时保证 Windows 页面文件有一定余量双管齐下。7. 我的配置习惯和几个最后的提醒文章写到这里最后分享一点我自己的配置习惯仅供参考。我的主力工作机是 32GB 内存、512GB NVMe SSD。C 盘页面文件固定设置为 8192MB 到 16384MB也就是初始 8192、最大 16384。原因是 WSL2、Electron 应用、浏览器组合起来提交量峰值经常能到 40GB 左右固定一个 16GB 的页面文件能让提交上限保持在 48GB 左右留有足够余量。另一台 16GB 内存的办公本我会把页面文件统一设成固定 16384MB省心也不会因为 Chrome 标签页开多了就弹“内存不足”。如果你用的是 64GB 以上内存的机器我大概率会建议直接恢复“自动管理所有驱动器的分页文件大小”然后定期观察提交量。系统托管并不是“不设置”而是把专业的事交给 Windows 的内存管理器去动态决策。很多人觉得自动管理不专业其实在内存充裕的场景下它确实是最均衡的方案。最后三个提醒都是踩过坑换来的第一任何配置改动后都要重启验证。不要改完就以为完事了至少重启一次然后重新查看页面文件使用命令确认目标盘的页面文件路径和大小都符合预期。第二定期清理 C 盘空间防止页面文件动态扩展时因磁盘空间不足而崩溃。如果你用系统托管一定要留意 C 盘剩余空间最好预留不低于 20GB否则页面文件和休眠文件抢空间系统会变得很怪。第三不要同时贪多设置多个磁盘的页面文件。我曾经在 C 盘和 D 盘各放一个页面文件以为能提升性能实际效果是系统把负载分散到了两块盘上但因为 D 盘是 SATA 接口反而把整体换页速度拖慢了。多盘页面文件适合真正有 IO 隔离需求的环境普通用户设一个就够。虚拟内存这个话题看似基础但大多数 Windows 性能问题和“内存不足”报错最后都能追溯到页面文件设置不合理。花十分钟把它的原理和当前状态搞清楚比盲目加内存条更能解决实际问题。
返回列表