WSL 的 ext4.vhdx 文件太大了,怎么清理?

先清理,再关闭,最后压缩

最近清理 C 盘的时候,发现有个文件特别大:

C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_xxxxx\LocalState\ext4.vhdx

我这里这个文件一度有 56GB 左右。

这个文件是 WSL2 的虚拟磁盘文件。Ubuntu 里的文件、缓存、Docker 镜像等,基本都存在这里。问题是:你在 WSL 里面删除了文件,Windows 里的 ext4.vhdx 不一定会自动变小

所以正确处理方式是:

先清理 WSL 内部空间
再关闭 WSL
最后压缩 ext4.vhdx

下面记录一下完整步骤。


1. 找到 ext4.vhdx 的位置

先打开 PowerShell,执行:

$distro = Get-ChildItem 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss' | Where-Object { $_.GetValue('DistributionName') -eq 'Ubuntu' }

然后执行:

$path = Join-Path $distro.GetValue('BasePath') 'ext4.vhdx'

再输出路径:

$path

我这里得到的是:

C:\Users\14869\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx

如果你用的是别的发行版,比如 Debian,就把上面命令里的 Ubuntu 改成对应名称。

也可以先看一下有哪些 WSL 发行版:

wsl -l -v

2. 查看 ext4.vhdx 当前大小

PowerShell 里执行:

"{0:N2} GB" -f ((Get-Item $path).Length / 1GB)

如果你不确定 $path 有没有设置成功,也可以直接写完整路径:

"{0:N2} GB" -f ((Get-Item "C:\Users\14869\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx").Length / 1GB)

注意把路径换成你自己的。


3. 进入 Ubuntu 清理内部空间

先进入 WSL:

wsl -d Ubuntu

进入 Ubuntu 后,先清理 apt 缓存和无用包:

sudo apt autoremove --purge -y
sudo apt clean

清理 systemd journal 日志:

sudo journalctl --vacuum-time=7d

清理当前用户缓存:

rm -rf ~/.cache/*

然后可以看看哪些目录比较大:

du -xh -d 1 ~ 2>/dev/null | sort -h

再看一下 /var

sudo du -xh -d 1 /var 2>/dev/null | sort -h

如果装过 Docker,Docker 通常会占不少空间,可以先查看:

docker system df

如果确认旧镜像、旧容器、构建缓存都不需要了,可以清理:

docker system prune -a
docker builder prune -a

这里要注意,docker system prune -a 会删除未使用的镜像、容器、网络等。删完之后,以后项目需要的话可能要重新拉镜像。

清理完退出 Ubuntu:

exit

4. 关闭 WSL

回到 PowerShell,执行:

wsl --shutdown

再确认一下状态:

wsl -l -v

看到类似这样就可以了:

NAME STATE VERSION
* Ubuntu Stopped 2

这一步很重要。WSL 没有完全关闭的话,后面压缩虚拟磁盘可能失败。


5. 用 diskpart 压缩 ext4.vhdx

接下来要用 管理员身份运行 PowerShell

打开管理员 PowerShell 后,输入:

diskpart

进入 DISKPART> 之后,依次执行下面几行。

把路径换成你自己的 ext4.vhdx 路径:

select vdisk file="C:\Users\14869\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit

其中真正压缩的是这一句:

compact vdisk

这个过程可能会等一会儿。磁盘越大时间越长,等它执行完就行。


6. 再检查一次大小

压缩完成后,可以再执行:

"{0:N2} GB" -f ((Get-Item "C:\Users\14869\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx").Length / 1GB)

或者用磁盘分析工具重新扫一下。

如果大小下降了,说明清理成功。

如果没什么变化,一般有两个原因:

  1. WSL 里面实际还有很多文件没删掉。
  2. Docker、模型文件、项目依赖缓存之类的内容还在。

可以回到 Ubuntu 里继续查:

du -xh -d 1 ~ 2>/dev/null | sort -h
sudo du -xh -d 1 /var 2>/dev/null | sort -h
docker system df

最后总结

WSL 的 ext4.vhdx 变大后,不要直接去删这个文件。

这个文件就是整个 Ubuntu 的磁盘,删了基本等于把 WSL 系统删了。

正确流程是:

1. 进入 Ubuntu 清理缓存、日志、Docker 等内容
2. 执行 wsl --shutdown 彻底关闭 WSL
3. 用 diskpart 的 compact vdisk 压缩 ext4.vhdx

以后如果发现 C 盘又被 WSL 吃掉很多空间,可以按这个流程再来一遍。