如果你曾经在 Windows 上安装过 WSL 或 Docker,现在就检查这个文件夹
如果你在 Windows 上安装了 WSL、Docker Desktop 或 Hyper-V,很有可能你的硬盘上有一个文件占用了 30、40,甚至 50 GB 的空间。你在常用的清理位置是看不到它的,包括下载文件夹、回收站,甚至存储感知也无法发现它。它就静静地存在在那里,不断增长,埋藏在大多数人从未打开过的文件夹里。
该文件是 VHDX,这是这些工具用于存储你的 Linux 发行版、容器和虚拟机内部所有内容的虚拟磁盘映像。问题是 VHDX 文件会随着使用而增长,但即使删除其中的内容也不会自行缩小。无论你启动了几个容器、拉取了一些镜像,还是一周后删除了它们,文件都会保持在达到的最大大小。如果你使用这些工具已有一段时间,值得检查这些文件夹以释放一些可观的存储空间。
膨胀隐藏的地方
在您的电脑上需要检查的确切文件夹
我第一次去找这些文件时,不知道从哪里开始。位置取决于你运行的是哪种工具,但每个工具的 VHDX 文件都会放在一个可预测的位置。对于 WSL,打开文件资源管理器,在地址栏粘贴 %LOCALAPPDATA%\Packages。寻找以 CanonicalGroupLimited 开头的文件夹(用于 Ubuntu)或你的发行版的发布者名称。在 LocalState 子文件夹中,你会找到 ext4.vhdx。这个单独的文件包含了你整个 Linux 文件系统。
Docker Desktop 会将其磁盘保存在 %LOCALAPPDATA%\Docker\wsl 下的一个名为 docker_desktop.vhdx 或 disk\docker_data.vhdx 的文件中,具体取决于你的版本。Hyper-V 虚拟机的位置由你配置,但默认位置是 C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks。
文件大小是情况有点奇怪的地方。我曾经看到 WSL 在应用和功能中显示为 583 GB,而在 Ubuntu 内部使用 df -h 命令时却只报告使用了 93 GB。这中间有 490 GB 的差距,却没有任何迹象显示这些空间被使用了。你可能首先会猜测 /mnt/c 被计算在内,因为 Windows 默认会在 WSL 中挂载你的 C: 盘,但事实并非如此。VHDX 本身只是从未释放那些空间。
要检查您自己的文件,请在文件资源管理器中右键点击 ext4.vhdx 或 docker_data.vhdx,然后查看 磁盘上的大小 值。这就是最重要的数字,通常也是让人感到意外的数字。如果它比您在发行版或容器中实际拥有的内容要大,那么本文的其余部分就是为您准备的。
为什么 VHDX 文件不会自动缩小
这是一个故意的设计选择,而不是一个错误
这听起来像是微软的疏忽,但实际上这是一个故意的选择。WSL 使用动态扩展的 VHDX,所以你不必事先为硬盘预分配一大块空间。磁盘会根据需要增长,这很好,直到你想要回这些空间的时候。
它不会自动缩小的原因也很有趣。如果你的工作负载始终保持在一个稳定的大小,比如一个大小在 32 GB 左右,波动一两 GB 的项目,自动缩小意味着磁盘会不断地缩小和重新增长。这种频繁的变化对性能不好,对 SSD 的磨损更糟。同样的逻辑也适用于一天中不断启动和销毁的 Docker 容器。
所以微软选择让文件不断增长并保持增长状态,把手动清理留给用户。这对于大多数工作负载来说是正确的选择,但这确实意味着你需要知道这个技巧的存在。否则,你会一直想不明白为什么即使删除了 WSL 内的内容或清理了 Docker 镜像,你的 C: 盘看起来仍然很满。Linux 侧报告空间是空闲的,而 Windows 侧却一直占用它,而且两个工具都不会告诉你这种不匹配情况。
如何回收空间
压实过程及其注意事项
清理是一个两步的过程,而大多数指南出错的地方在于跳过第一步。在压缩之前,你需要先对 WSL 内的空闲空间进行零填充,因为稀疏的 VHDX 只能在看到连续的零时才能被缩小。如果跳过这一步,Optimize-VHD 会顺利运行,但文件大小几乎没有变化。你按照步骤操作,看不到变化,就会以为这个技巧无效。
在你的 WSL 发行版中,运行 dd if=/dev/zero of=/zerofile bs=1M; rm /zerofile。此操作会向磁盘写入零直到磁盘满,然后删除该文件,从而为你留下干净、紧凑的空间。该命令最终会因 设备上没有空间 错误而失败,这正是你想要的。如果你通过 WSL2 运行 Docker,请先停止 Docker Desktop 并备份任何重要数据,因为一些用户报告在压缩后容器可能会损坏。
然后,在 PowerShell 中运行 wsl --shutdown,导航到包含 VHDX 的文件夹,并运行 Optimize-VHD -Path .\ext4.vhdx -Mode full。这需要安装 Hyper-V 功能,这意味着需要 Windows Pro 或 Enterprise。在家庭版上,你会遇到错误。备用方法是 diskpart:以管理员身份打开它,然后运行 select vdisk file="C:\path\to\ext4.vhdx",随后运行 attach vdisk readonly、compact vdisk 和 detach vdisk。这方法虽然笨拙,但在没有 Hyper-V 的情况下也能使用。
不要让这成为例行维护
压缩功能有效,在一个膨胀的 WSL 安装中,你可以轻松回收一百 GB 或更多空间。但值得记住的是,微软之所以这样设计,是有原因的。每周运行 Optimize-VHD 与其设计理念相悖,并且会为微不足道的收益增加 SSD 的不必要写入周期。
我会在注意到驱动器变得紧张或在 WSL 内进行大清理之后运行这个,比如删除旧的 Docker 镜像或清理一些项目文件夹。平时,我不会去动它。如果你的磁盘空间普遍不足,这是你可以做的最有价值的清理之一。只是不要把它设置为定时任务。







