资讯动态

WSL2 VHD膨胀占满C盘?用fstrim+diskpart压缩回收空间

发布时间:2026/10/20 3:12:08 来源:尧图企业网站定制
1. 为什么 WSL2 会把 C 盘撑爆从 VHD 的只进不出说起如果你用 WSL2 开发某天突然发现 Windows 的 C 盘红了清理了临时文件、卸载了不用的软件还是没缓解这时候很大概率就是 WSL2 的虚拟磁盘文件在作怪。WSL2 的整个 Linux 文件系统并不是直接放在 Windows 目录里的而是封装在一个扩展名为.vhdx的虚拟磁盘文件中默认存放在类似C:\Users\你的用户名\AppData\Local\Packages\...\LocalState\目录下。这个文件的特性很关键它只懂得不断扩张却不主动缩小。默认情况下WSL2 给到的虚拟磁盘大小上限是 1TB部分版本默认 256GB但最坑的地方在于它采用了一种需要多大就涨多大但绝不小回去的动态扩展机制。你用apt install装了几个大型开发包、拉取了 Docker 镜像、跑模型训练、在 Linux 里解压了几个大文件VHD 文件就会跟着膨胀。问题出在删除行为上你在 Linux 侧删除了文件Linux 文件系统会把这些块标记为空闲但底层虚拟磁盘并不知道这些块已经没用了它不会主动回收于是空间就白白占着。这就好比租了一个能自动扩容的仓库老板说你搬走多少东西就退多少租金结果老板反悔货物搬走了仓库还是占着你原来的租金。VHD 文件一旦膨胀到 30GB、50GB甚至 100GB想拖回去就只能靠手动干预。这里说的压缩 VHD 回收 Windows 空间本质上就是完成两件事让 Linux 文件系统把空闲块归零或整理标记然后让虚拟磁盘层真正把未使用的块收缩回去。说白了先让 Linux 内部知道自己有哪些空间真正没用了再用 Windows 侧的磁盘工具把 VHD 按实际使用量压缩最终让 C 盘空间实实在在空出来。这个问题的坑在于官方 WSL 设置里没有一键回收空间的可视化按钮命令行工具和手动操作流程分散在不同子系统间大部分人第一次处理都会踩坑比如压缩无效、VHD 损坏、WSL 起不来等。这篇文章要做的就是打通整个流程原理说透、步骤细化、参数讲清、问题列明让没有玩过磁盘虚拟化的人也能照着操作回收几十 GB 空间。2. 动手前必须弄懂你其实在和 VHDX 的两层结构打交道2.1 WSL2 的存储路径与虚拟磁盘形态先说路径。WSL2 发行版比如 Ubuntu-22.04、Debian 等的虚拟磁盘路径隐藏在 Windows 包目录下常规目录为C:\Users\你的Windows用户名\AppData\Local\Packages\ 发行版对应包名\LocalState\ext4.vhdx如果你是通过微软商店安装的 Ubuntu包名一般是CanonicalGroupLimited.Ubuntu...或类似命名。不确定时可以打开 PowerShell 执行命令来定位Get-AppxPackage | Where-Object { $_.Name -like *Ubuntu* -or $_.Name -like *Debian* } | Select-Object Name, InstallLocation拿到 InstallLocation 后再往里面找LocalState就能看到ext4.vhdx或类似名字的虚拟磁盘文件。注意如果你是手动导入的发行版路径不在这里需要用wsl --shutdown后去你当时指定的安装目录查找。这个文件就是整个 Linux 系统的硬盘镜像。WSL2 在虚拟机内部把它当作一块原生磁盘来用格式化成了 Linux 常用的 ext4 文件系统。Windows 侧只是把它当作一个普通的 VHD/VHDX 磁盘文件来进行读写。所以压缩 VHD 的空间必须先穿过两层Windows 侧的 VHDX 容器层以及 Linux 侧的文件系统层。2.2 压缩的前提Linux 文件系统要告诉磁盘哪些块是空闲的Windows 的diskpart或Optimize-VHD工具在压缩 VHD 的时候需要知道这块虚拟硬盘里哪些扇区是没用的。对普通 NTFS 格式的 VHD 来说Windows 自己就能识别文件系统空闲块但对 WSL2 这种使用 ext4 格式的 VHD 来说Windows 侧是没法直接解析 ext4 的空闲块信息的。所以必须先回到 WSL2 里面用 Linux 自己的工具把还在占用和已经空闲的分界理清楚。在 ext4 文件系统上主流做法是执行fstrim命令。这个命令的作用是遍历整个文件系统把未使用的块用 DISCARD/TRIM 操作通知给底层存储。对 WSL2 这种虚拟化环境来说这些 DISCARD 操作其实是在更新虚拟磁盘内部块的空闲记录。效果是VHD 文件内部空闲区域的数据映像变成全零或统一的未使用标记压缩工具才知道这些块可以回收。如果你跳过了fstrim直接在 Windows 侧执行压缩操作结果往往是压缩量为零或压缩了但只回收了几百 MB。我在最初处理这个问题时就犯过这个错——在 PowerShell 里对着 VHD 执行compact vdisk提示完成 100%但查看文件大小几乎没变就是因为没先回到 Linux 侧做fstrim。所以压缩流程是有严格顺序的先关机、再做文件系统整理、再压缩虚拟磁盘顺序不可颠倒。2.3Optimize-VHD与diskpart两种压缩路径的取舍一旦 WSL2 内部把空闲整理完成了Windows 侧的压缩就有两个选择一个是 PowerShell 的 Hyper-V 模块里的Optimize-VHD另一个是所有 Windows 都自带的diskpart命令。Optimize-VHD的用法Optimize-VHD -Path C:\path\to\ext4.vhdx -Mode Full它的-Mode参数有Full完整压缩、Retrim快速重新裁剪、Pretrim预裁剪几种这里最常用的是Full或Retrim。Optimize-VHD的好处是专门为虚拟化场景设计压缩效果稳定但问题是它依赖 Hyper-V 的 PowerShell 模块并不是所有 Windows 默认安装的可能需要手动启用 Hyper-V 管理功能或者在新版 Windows 里通过启用或关闭 Windows 功能添加。diskpart则是一个更原生的工具对 Windows 10 和 Windows 11 的家庭版、专业版都有效不需要额外安装 Hyper-V。操作方式也比较固定diskpart select vdisk fileC:\path\to\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exit这里是否需要attach vdisk readonly不同 Windows 版本有差异。在部分 Windows 11 版本中挂载 VHD 时不指定readonly会导致无法压缩或提示磁盘被占用但也有人在attach vdisk readonly模式下会报参数不正确之类的错误。我实测下来如果你在diskpart主界面执行attach vdisk readonly遇到问题可以先尝试直接attach vdisk不加 readonly再compact vdisk反之如果磁盘忙或压缩失败就加上 readonly 重试。后续讲问题排查的时候我再细说这个坑。Optimize-VHD在底层逻辑上更安全、压缩算法更智能在多版本 Hyper-V 场景下表现更好diskpart则胜在普遍可用、命令简洁。普通用户我推荐先尝试diskpart实在不行再启用 Hyper-V 模块使用Optimize-VHD。它们的本质一样读取 VHD 内部的空闲块位图把被标记为未使用的空间从 VHD 容器中移除从而减小文件大小。3. 实操核心流程从 WSL 内部整理到 Windows 侧压缩3.1 第一步彻底关闭 WSL2避免文件锁占用压缩操作前最忌讳的是 WSL2 虚拟机还在运行或至少相关的进程没退出。因为只要 WSL2 还在运行ext4.vhdx文件就处于被占用状态Windows 侧的磁盘工具根本没法正常打开它。最安全的方式是执行完全关机wsl --shutdown这个命令会把所有 WSL2 发行版全部停止。在 Windows 10 和 Windows 11 上执行后等一两秒再用wsl --list --running验证输出里没有任何发行版正在运行。还有一个隐藏坑就算你关掉了 WSL 窗口后台可能还有wslhost.exe、vmmem进程活着。多等一会儿再操作或者在任务管理器里确认没有 WSL 相关进程占用 VHD。如果你开启了 WSL 的局域网自动转发或本机这个那个服务也可能会让 VHD 文件在后台被引用。最稳妥的操作顺序是先退出所有 WSL 终端窗口 → 执行wsl --shutdown→ 等待 5-10 秒 → 检查运行状态 → 再开始压缩。3.2 第二步进入 WSL2检查并清理文件系统这一步的目标是先把 WSL2 内部不必要的文件清理掉再执行fstrim。很多人压缩 VHD 后发现空间回收不多不是工具的问题而是因为 Linux 文件系统本身还大量占用着空间。比如/var/log下可能有几十 GB 的日志、~/.cache里有大量缓存、Docker镜像残留的悬空层等这些都会影响压缩率。进入 WSL2 后可以先看磁盘占用趋势df -h /df -h会告诉你/根文件系统总量和使用量。比如ext4.vhdx是 40GB但df -h /显示已用 10GB、可用 30GB那理论上压缩后 VHD 应该从 40GB 降到 10-11GB 左右。但如果df -h显示已用 30GB那说明你真正该做的不是压缩而是清理。常见的清理动作# 清理 apt 缓存 sudo apt-get clean # 清理日志 sudo journalctl --vacuum-size200M # 清理当前用户缓存 rm -rf ~/.cache/* # 清理 Docker 占用的悬空资源 docker system prune -a这些按需执行不需要贪多。清理到df -h显示的使用量明显下降后再执行空块整理sudo fstrim -v /fstrim执行后会输出 /: 12.3 GiB (131783玻璃195 bytes) trimmed 之类的结果。这个数字表示整理出的空闲块大小通常越接近你在df -h看到的可用空间后续压缩效果就越明显。如果执行fstrim报错或者没反应可能是你的内核或文件系统不支持 discard但绝大多数 WSL2 默认内核是支持的。Windows 11 的 WSL 版本在fstrim支持方面比较完善Windows 10 的旧版 WSL 可能要先把 WSL 更新到最新版本后面我展开讲。3.3 第三步再次彻底关机并记录压缩前的 VHD 大小fstrim执行完成后必须再执行一次wsl --shutdown很多人以为上一步退出 WSL 窗口就行但fstrim是在 WSL 里做的WSL 进程又起来了必须再关一次。然后去 ext4.vhdx 所在目录查看文件当前大小作为压缩前基准。在 PowerShell 里可以用(Get-Item C:\path\to\ext4.vhdx).Length / 1GB这个数值是你将要回收的起点。举个例子VHD 当前 50GB但在 WSL 里df -h只显示已用 15GB意味着理论上可以回收 35GB 左右。当然实际压缩可能不会完美到 15GB因为文件系统元数据、虚拟磁盘内部结构会有少量开销但压缩后大小应该非常接近df -h的已用数值而不是原来的 50GB。3.4 第四步用 diskpart 压缩 VHD附详细命令与解释打开 Windows 的 CMD 或 PowerShell建议用管理员身份启动。执行diskpart进入diskpart交互环境后依次输入select vdisk fileC:\path\to\ext4.vhdx注意路径不要放在中文目录或者名字包含空格的路径里如果有空格用引号包住整个路径。然后attach vdisk readonly这一步是挂载 VHD 文件到系统中只读方式是为了避免在压缩过程中有任何写操作触发 VHD 内部状态变化。挂载成功后执行压缩compact vdiskcompact vdisk会读取 VHD 内部的未使用块信息然后把文件体积缩小。这个过程可能持续几秒到几分钟取决于 VHD 大小和磁盘速度。等它显示 DiskPart 已成功压缩虚拟磁盘文件 后执行detach vdisk然后exit退出 diskpart。这时候再回看 VHD 文件属性大小应该明显缩小。我在一台实际测试环境上做了验证处理前的 ext4.vhdx 是 47.8GBfstrim后压缩到 18.3GB直接给 C 盘腾出了近 30GB 空间。3.5 第五步重启 WSL2 并确认系统正常压缩完成后重新打开 WSL2 终端。正常情况下会像什么都没发生过一样进入系统。用df -h /确认磁盘空间和文件没有异常。如果出现启动失败、提示虚拟磁盘已损坏或文件系统检查卡住多半是前面某一步没做对或者 VHD 文件本身已有问题下文会详细讲排查方法。恢复 WSL2 后还有一个可选操作保险起见用sudo fsck -f /在启动时做一次文件系统完整性检查但不是每次都需要。如果你平时的 WSL 版本一直稳定压缩流程正确问题不大。4. 核心原理补充fstrim、TRIM 与 VHD 动态裁减的关系4.1 TRIM/DISCARD 到底在底层做了什么很多人只知道压缩 VHD 要运行fstrim但不明白为什么它能帮助回收 Windows 空间。这里补一个基础概念SSD 时代的 TRIM 指令本质上是操作系统在删除文件时将不再使用的逻辑块地址LBA告诉存储设备。存储控制器知道这些块可以擦除/回收性能就不会因为写入新内容还要先擦旧内容而变慢。WSL2 的虚拟磁盘文件虽然是单个文件但对虚拟化层来说它仍然要模拟一块真实磁盘。当 ext4 文件系统删除文件时它通常只会修改自己的元数据把对应块标记为空闲并不会主动通知虚拟磁盘底层。如果一直不通知VHD 内部所有的块都会保持被占用的状态。fstrim就是遍历整个文件系统把每个未使用的块都向底层的块设备发送 DISCARD/TRIM。虚拟机监控器WSL2 下是 Hyper-V 架构收到这些指令后更新虚拟磁盘的内部状态把对应的块标记为未被分配。压缩工具如 diskpart 的 compact再去读取这个未分配信息自然就知道哪些空间可以释放。整个过程就像整理一间堆满旧家具的屋子fstrim是贴上可丢弃标签、清点需要搬走的东西compact才是真正把这些东西搬出去、缩小仓库面积。4.2 为什么有些人压缩完 VHD 没小多少——三种典型原因压缩收益不理想绝大多数情况是下面三种问题第一种没有真正清理 Linux 文件系统。VHD 本身已经水分极少所有空间都是数据本身。这时无论怎么fstrim、怎么 compact都只能缩小几 MB。解决办法是回到 WSL2 中清理不必要的包、缓存和日志后再执行压缩。第二种fstrim执行有问题或者根本没有成功整理出空闲块。可能表现为执行fstrim -v输出0 B (0 bytes) trimmed这时候compact就没有任何可回收信息。一句话判断看fstrim的输出值是不是 0如果是说明文件系统没被正确裁剪要先排查。第三种压缩工具执行时机不对——没有执行wsl --shutdownVHD 处于使用中compact vdisk虽然显示成功但实际只是空转。可以观察 VHD 文件修改时间如果压缩操作后文件修改时间都没变化说明根本没起作用。4.3 VHD 格式本身的碎片损耗即使把上面所有步骤做对最终压缩完的大小也很少会完美等于df -h的已用空间。原因有两层一方面ext4 文件系统的元数据超级块、inode 表、位图等本身需要占用空间另一方面VHDX 格式内部还有分块映射表、元数据区域等额外结构。一般来说压缩后的文件大小在已用空间1-2GB这个范围内都是正常的不用为了多回收几百 MB 反复操作。这里还引申出一个习惯问题把 VHD 压缩当成定期维护项而不是等 C 盘满了才想起。我的周期建议是一个月执行一次fstrim当 VHD 文件膨胀到接近df -h两倍时安排一次完整压缩。这样可以避免 C 盘长期处于临界状态。5. 常见问题与疑难排查压缩过程中最常见的 8 个坑5.1attach vdisk readonly报错或无法挂载diskpart中执行attach vdisk readonly时有时会提示虚拟磁盘服务错误指定的文件不是虚拟磁盘文件或函数不正确。先检查几件事VHD 文件路径是否正确select vdisk是否提示成功WSL2 是否真的关闭了可以打开任务管理器确认没有wslhost.exe占用 VHD确认文件后缀是不是.vhdx如果系统是 WSL 本身生成的.vhdx正常没问题。如果加了 readonly 挂载有问题我有一次尝试直接attach vdisk不加只读参数结果 diskpart 提示需要管理员权限加了管理员权限后就没问题。也有时候 readonly 挂载会触发 WSL 自动挂载的机制造成文件又处于占用状态所以建议压缩前临时断开所有能访问 VHD 的程序包括文件资源管理器里打开的 ext4.vhdx 挂载盘符。5.2fstrim报错fstrim: /: the discard operation is not supported在 WSL2 里执行fstrim -v /报不支持的情况多出现在老版本的 WSL2 或自定义内核环境下。可以先更新 WSLwsl --update更新后重启 WSL 再试。如果依然不行检查内核 modules/lib/modules是否存在对应版本。极端情况下可以试试卸载重装发行版但那是最后选择。大多数环境在wsl --update后能解决。还有一种情况是fstrim对根文件系统报错但对/home之类的挂载点正常。那说明根目录所在的块设备不支持。WSL2 默认只有一个融合挂载的根文件系统一般不区分这些。普通 Ubuntu 发行版从商店安装的默认环境没这种问题。5.3compact vdisk执行了但文件大小没变如果df -h显示空闲很多fstrim输出也正常但 compact 后文件大小没变大概率是fstrim和compact之间中间又有一层写缓存没落盘。可以尝试在 WSL2 里执行sync命令后再关机关机后等 10 秒再执行 diskpart换用Optimize-VHD -Mode Full再试一次。如果Optimize-VHD也压缩不了极可能是 VHD 文件被微软商店或 Hyper-V 管着存在某种锁。这种情况下关闭所有 WSL 进程、重新启动电脑后再试成功率会高很多。5.4 WSL2 压缩后系统无法启动或文件异常压缩完 VHD 后启动 WSL2 时报WSL 内部错误或找不到指定的文件基本都是压缩过程中 VHD 文件被错误写入或者路径不对。紧急处理方法检查 ext4.vhdx 是否还有备份如果没有备份且系统打不开先别慌运行wsl --shutdown后重新用wsl -l -v查看发行版状态。如果只是 VHD 文件丢失能通过安装目录下的.vhdx检查如果确实是 VHD 损坏可以从 Windows 的时间点还原功能恢复如果开了文件历史记录或卷影复制。预防永远大于补救压缩前一定要为ext4.vhdx做一个备份。VHD 文件是几十 GB 的话备份时间不短但拿一个移动硬盘备份 1-2 次比系统起不来、环境全丢损失小得多。注意直接把 VHD 压缩后重新挂载有时会导致 ext4 文件系统认为磁盘大小变化而自动调整但这种调整一般发生在启动阶段不会主动破坏数据。真遇到了可以挂载到另一台 Linux 环境下用e2fsck修复但一般用户建议先重装 WSL 发行版并恢复备份数据。5.5 压缩后文件依然比预期大很多有一种情况是 WSL2 里有多个发行版每个发行版都有独立的.vhdx。找到对应的那个再操作。如果你安装的发行版加入了自定义数据盘比如自己挂载了第二块虚拟磁盘那块盘也需要单独处理。先把所有发行版和虚拟磁盘列全再动手。Get-VM | Select-Object Name, Path # 或 diskpart list vdisklist vdisk会列出当前系统所有挂载的 VHD 文件能看到具体路径和状态帮助判断是不是漏掉了一个大文件。5.6 为什么压缩必须管理员权限diskpart和Optimize-VHD需要管理员权限的原因是它们要访问系统级磁盘管理接口普通用户没有权限对卷或虚拟磁盘执行挂载、压缩等操作。如果你在普通 PowerShell 里执行磁盘挂载和压缩都会报拒绝访问。解决办法很简单右键 PowerShell/CMD选择以管理员身份运行。这个细节没处理好后面操作全卡壳。5.7 压缩 VHD 和 Windows 11 的 WSL 自动回收功能Windows 11 的较新版本引入了 WSL 的虚拟磁盘自动回收能力只要你开启了自动回收空闲空间的设置WSL 会在后台判断虚拟磁盘的空闲量并在安全时机进行收缩。这个功能默认是否开启取决于具体的 WSL 版本可以在.wslconfig文件里配置[wsl2] autoMemoryReclaimgradual sparseVhdtrue其中sparseVhdtrue可以让 VHD 以稀疏文件方式创建即按需占用而不是预分配整整一个文件大小。如果你的 WSL 已经开了这个功能新创建的发行版卷会更省空间。不过对于已经膨胀的老 VHD还是要手动走一遍fstrim 压缩。这个功能和手动压缩并不冲突手动压缩是主动立竿见影自动回收是日常保鲜。而且注意新版本 WSL 在使用sparseVhdtrue时compact vdisk可能返回的大小变化不明显因为 VHD 底层文件本身就是稀疏的物理占用已经比较小。这时候可以通过文件属性里的占用大小而不是大小来判断收益。5.8 压缩能否直接把磁盘类型从动态转固定这是一个常见误解。compact vdisk只做一件事收缩动态扩展虚拟磁盘的体积它不会把动态 VHD 变成固定大小 VHD也不会减少df -h里的容量上限。如果你有一个 100GB 上限的动态 VHD实际只用了 8GB压缩后文件大小可能接近 8-10GB但 WSL 里看根分区容量上限还是 100GB或你设定的值。这是正常的因为压缩是针对物理文件占用的空间虚拟磁盘的逻辑容量并没有变。如果你想修改虚拟磁盘逻辑容量上限那需要做 resizing属于另一个操作不是本文讨论的回收 Windows 空间。6. 实操回顾与量化收益一次完整压缩的全记录为了更有参考价值我以自己的一个模拟项目环境为例完整走了一遍流程并记录了关键数据。环境是Windows 11 专业版 WSL2 Ubuntu 22.04ext4.vhdx 位置在默认系统路径。当时刚跑完一个图像处理相关的 Python 项目拉过多个 Docker 镜像、装过 PyTorch 等大件C 盘空间告急检查时发现 ext4.vhdx 高达 47.8GB。第一步进 WSL2 执行df -h /显示已用 17.2GB可用 30.6GB——理论上最高回收空间约 30GB。我先执行了sudo apt clean清理约 2-3GB 缓存、sudo journalctl --vacuum-size200M、docker system prune -a清掉了几个悬空镜像和 build cache。再次查看df -h已用降到 15.1GB。然后执行sudo fstrim -v /输出大概为/: 31.9 GiB (342 亿字节) trimmed这说明有 31.9GB 空闲块被正确标记。随后退出 WSL 并执行wsl --shutdown等待 5 秒后确认wsl --list --running为空。管理员身份打开 PowerShell进入 diskpartselect vdisk fileC:\Users\某用户\AppData\Local\Packages\...\LocalState\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exit整个过程不到 30 秒就完成了。再去查看 ext4.vhdx 属性大小变成了 17.3GB比预期略大一点但回收了 30.5GB 空间。重新打开 WSL2运行df -h /正常文件和数据完全没丢。对 C 盘来说一个 30GB 的空间压力直接清零系统运行明显流畅。这次实操验证了一个关键点fstrim输出trimmed 31.9 GiB和最终压缩后回收 30.5GB 基本对齐说明压缩依据的就是fstrim标记的空闲量。如果没先做这个步骤直接压缩 47.8GB VHD最终能回收的空间恐怕不到 2GB——这也是很多教程没说透的地方。7. 附带技巧如何设置自动瘦身防止再次膨胀压缩一次解决不了长期问题。尤其是那种每天都要拉 Docker 镜像、装包再删包的高频开发流VHD 膨胀速度极快。与其每个月手动处理不如把自动回收配置提前设好。在 Windows 用户目录下创建/编辑.wslconfig文件比如C:\Users\某用户\.wslconfig加入[wsl2] autoMemoryReclaimgradual sparseVhdtrue然后执行wsl --shutdown让配置生效。autoMemoryReclaimgradual是控制 WSL2 内存自动回收sparseVhdtrue是让 VHD 变成稀疏文件两者配合能减少不少系统资源浪费。不过要注意配置只对之后新创建或 rebuild 的发行版生效对现有 VHD 不一定立刻产生效果所以还是要先把现有 VHD 手动压缩一次再开启配置防止未来再次膨胀。对于长期使用者还可以给自己设置一个压缩提醒比如用任务计划程序每月执行一个脚本先wsl --shutdown然后运行 diskpart 的 compact 命令。不过提醒一点压缩脚本如果遇到 VHD 被占用会自动失败不会造成损坏因此自动化可行。也有人写一个 PowerShell 脚本把fstrim也一起封装了思路是先启动 WSL 执行 fstrim再 shutdown再 compact。这个方案做得好几乎是无感的但前提是脚本编写要严谨比如判断发行版是否运行、等待 WSL 完全退出等否则容易白跑或者遇到文件锁问题。个人体验上自动化不要追求全自动无脑跑最好搭配日志输出。因为 VHD 在压缩时不能处于使用状态如果某个时间点你刚好开着 WSL 写代码脚本自动强制 shutdown 可能会打断工作。我自己的做法是设置每日凌晨 3 点执行fstrim此时我基本不会开 WSL然后每周日凌晨 4 点执行压缩。这个频率下VHD 不会堆积到几十 GB 才处理也不会频繁触发文件系统元数据的大改动。8. 经验总结这些细节决定压缩成败最后把我踩过的坑和感悟逐条列出来当作速查清单压缩前一定先看df -h /确认已用空间和总容量的差距。如果差距很小说明压缩空间不大先做系统清理比压缩 VHD 更实在。fstrim -v /的输出是判断能否压缩成功的关键指标。如果输出0 bytes trimmed别急着进 diskpart先排查 WSL 版本和磁盘挂载状态。wsl --shutdown必须在压缩前执行还要验证wsl --list --running为空否则 VHD 文件会被锁死。diskpart必须管理员权限attach vdisk readonly失败时换用直接attach vdisk或者重启后再试。压缩完成后文件大小与df -h已用空间之间的误差在 1-2GB 内都是安全的。如果差太多把 VHD 里的大型文件清理掉后再来一轮。如果是 Windows 11 新版 WSL可以先检查.wslconfig里的sparseVhd配置避免在稀疏文件上误判压缩效果。大项目或者数据重要的情况下备份 ext4.vhdx 是无脑正确的一步。几十 GB 的备份成本远低于数据重建成本。Optimize-VHD与diskpart不冲突压缩失败时交替使用是合理策略但不要同个时间段连续多次压缩给磁盘一点稳定时间。我自己处理过很多次 VHD 膨胀压缩完之后 C 盘空间恢复只是表面的收益真正的价值在于WSL2 变成了一块可以长期安心使用的开发盘不用再因为空间告急反复迁移环境或者删库重装。希望这篇内容能把你从VHD 越用越大、C 盘越来越红的循环里拉出来。按照上面的顺序操作一次成功概率极高如果中途卡在某一步顺着章节里提到的问题排查路径走基本都能找到症结。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑