资料
- Microsoft Learn:管理 WSL 磁盘空间
- Microsoft Learn:WSL 基本命令
- Microsoft Learn:compact vdisk
- microsoft/WSL#4699:WSL2 应该自动向宿主机释放磁盘空间
这算是 WSL2 很容易踩到的坑。发行版里的文件都放在 ext4.vhdx 中,这个动态虚拟磁盘会随着数据写入不断增大。问题出在删除文件以后:Linux 看到的可用空间回来了,Windows 上的 VHDX 文件却不会跟着变小。
我遇到过的情况很直接。构建缓存、容器镜像和临时文件清理完了,df 看起来很正常,C 盘空间却没有回来。微软的 compact vdisk 文档也明确写着,动态 VHD 会随数据增加而变大,但删除数据后不会自动缩小。WSL 仓库里的 #4699 从 2019 年就在讨论同一个问题。
默认安装目录也不好找
旧的商店 Appx 发行版通常把虚拟磁盘放在类似下面的位置:
C:\Users\USER\AppData\Local\Packages\CanonicalGroupLimited...\LocalState\ext4.vhdx新版 WSL 使用新的发行版架构后,也可能看到这种路径:
C:\Users\USER\AppData\Local\wsl\{GUID}\ext4.vhdx无论是带发布者后缀的包目录,还是只有一串 GUID 的目录,都不适合靠记忆寻找。PowerShell 可以从 WSL 的注册信息中取出准确路径:
$distroName = 'Ubuntu'
(Get-ChildItem -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss' |
Where-Object { $_.GetValue('DistributionName') -eq $distroName }
).GetValue('BasePath') + '\ext4.vhdx'不要在 AppData 里直接剪切正在使用的 VHDX。微软也提醒过,使用 Windows 工具随意修改这些文件可能损坏发行版。
我的习惯是放在 C:\app\wsl
我会把自己管理的软件放在 C 盘的 C:\app,WSL 也一样。这不是为了把文件赶到另一个盘符,而是为了让安装位置一眼就能找到:
C:\app\wsl\Ubuntu\ext4.vhdx新版 WSL 安装发行版时可以直接指定位置:
wsl --install --distribution Ubuntu --location C:\app\wsl\Ubuntu我当前使用的 WSL 也支持移动已有发行版:
wsl --shutdown
wsl --manage Ubuntu --move C:\app\wsl\Ubuntu先运行 wsl --help,确认本机有 --location 或 --move。版本太旧时不要手动搬 VHDX,可以沿用导出、注销、再导入的办法:
wsl --export Ubuntu C:\app\wsl\Ubuntu.tar
Get-Item -LiteralPath 'C:\app\wsl\Ubuntu.tar'
# 确认导出文件存在且大小正常后再注销
wsl --unregister Ubuntu
wsl --import Ubuntu C:\app\wsl\Ubuntu C:\app\wsl\Ubuntu.tar --version 2wsl --unregister 会删除原发行版。这里不能省掉导出文件检查,也不要在备份尚未完成时提前注销。
用 DiskPart 收回空间
先在 WSL 中删除确实不再需要的文件。然后关闭所有 WSL 实例;如果使用 Docker Desktop,也先退出它。
以管理员身份打开 PowerShell:
wsl --shutdown
diskpart进入 DiskPart 后执行:
select vdisk file=C:\app\wsl\Ubuntu\ext4.vhdx
attach vdisk readonly
compact vdisk
detach vdisk
exitcompact vdisk 只适用于动态扩展 VHD。磁盘需要处于分离状态,或者像这里一样只读挂载。路径也必须指向目标发行版,别在有多个 ext4.vhdx 时凭文件名猜。
如果提示文件正在使用,先检查 WSL 和 Docker Desktop 是否真的退出,再执行一次 wsl --shutdown。压缩完成后,Windows 上的 VHDX 文件会缩小;具体能收回多少,取决于发行版里有多少已经释放的磁盘块。
新版 WSL 还提供稀疏 VHD 选项,但不同版本上的回收效果曾经引起过不少讨论。我没有把它当成唯一保障。安装时指定 C:\app\wsl,需要时手动执行一次 compact vdisk,路径和结果都更容易确认。