WSL 磁盘空间救火手册:VHDX、Docker、模型缓存和真正能回收的空间
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。更完整的更新写在微信公众号「字与码」:工作经历、对新技术的想法,以及这些年走弯路的记录,会不定期发在那里。若觉得博客对你有用,欢迎顺手关注。
WSL 最容易让人崩溃的问题之一,是 C 盘突然满了。
你在 Ubuntu 里删了几十 GB 文件,df -h 看起来空出来了。回到 Windows 一看,C 盘还是没少。再打开目录,发现某个 ext4.vhdx 仍然巨大。
这不是错觉。WSL2 的 Linux 文件系统在 Windows 里通常是一个虚拟硬盘文件。Linux 里面删文件,只是让虚拟硬盘内部有了空闲块;Windows 看到的 VHDX 文件,不一定会立刻缩小。

这篇从一次真实的救火流程写起:开发机 C 盘只剩 2GB,WSL 里跑不动 Docker,Node 项目装依赖失败,本地模型也没法下载。目标不是炫技,而是把“查什么、删什么、怎么确认真的回收了”说清楚。
第一件事:分清 Linux 里空了,还是 Windows 里空了
先在 WSL 里看:
df -h
看当前发行版根文件系统:
df -h /
再看大目录:
du -h -d 1 ~ | sort -h
sudo du -h -d 1 /var | sort -h
如果装了 Docker:
docker system df
如果跑本地模型:
du -sh ~/.cache ~/.ollama ~/models 2>/dev/null
这些命令回答的是:Linux 内部是谁占了空间。
Windows 侧要看 VHDX。默认商店版 Ubuntu 的路径通常在:
%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu...\LocalState\ext4.vhdx
不同发行版名字不一样。可以在 PowerShell 里查:
wsl -l -v
再到 %LOCALAPPDATA%\Packages 里看对应发行版目录。
这里的关键是:du 变小,不代表 ext4.vhdx 立刻变小。
先删确定无害的东西
我会从低风险缓存开始。
apt 缓存:
sudo apt clean
sudo apt autoremove --purge -y
Python 缓存:
find ~ -type d -name '__pycache__' -prune -exec rm -rf {} +
find ~ -type d -name '.pytest_cache' -prune -exec rm -rf {} +
Node 项目的依赖不要全局乱删,先找:
fd -H '^node_modules$' ~/work -t d \
| xargs -r du -sh \
| sort -h
确认某些老项目不再需要,再删:
rm -rf ~/work/old-project/node_modules
Rust、Go、pnpm、Yarn、npm 也常见:
du -sh ~/.cargo ~/.cache/go-build ~/go/pkg/mod ~/.npm ~/.pnpm-store ~/.cache/yarn 2>/dev/null
不要一条 rm -rf ~/.cache 了事。很多工具缓存删了可以重建,但有些缓存里混着登录状态、下载中的模型、构建索引。先看清楚。
Docker 是空间黑洞,但也最容易误删
Docker 的空间占用要单独看:
docker system df
列出镜像:
docker image ls
列出卷:
docker volume ls
清理停止容器、未使用网络、悬空镜像:
docker system prune
如果确定未使用镜像也可以删:
docker system prune -a
卷最危险。很多数据库数据都在 volume 里。不要随手:
docker volume prune
除非你确认这些卷不含需要保留的数据。
我通常先输出一份清单:
docker system df -v > docker-space-before.txt
清理后再:
docker system df -v > docker-space-after.txt
这样出了问题至少知道删过什么。
本地模型缓存要设“仓库”,不要散养
AI 开发机很容易被模型缓存吃满。
常见位置:
du -sh ~/.cache/huggingface ~/.ollama ~/models 2>/dev/null
Hugging Face:
export HF_HOME="$HOME/models/huggingface"
export TRANSFORMERS_CACHE="$HF_HOME/transformers"
export HF_DATASETS_CACHE="$HOME/datasets/huggingface"
Ollama:
du -sh ~/.ollama 2>/dev/null
ollama list
如果模型不再需要,优先用工具自己的命令删:
ollama rm qwen2.5:7b
不要直接在模型目录里乱删单个 blob。很多模型管理器会用内容寻址、引用计数或 manifest。手工删除容易留下半残状态。
我会给本地 AI 项目定一个目录规范:
~/models/ # 模型权重
~/datasets/ # 数据集
~/runs/ # 实验输出
~/archive/ # 可清理归档
然后每周看一次:
du -h -d 1 ~/models ~/datasets ~/runs 2>/dev/null | sort -h
删除后,为什么 Windows C 盘还是没变小
因为你只是让 ext4 文件系统内部出现空闲块。VHDX 文件本身仍然可能保持原大小。
Microsoft 的 WSL 磁盘空间文档里提供了管理和调整虚拟磁盘大小的方法。新版 WSL 可以用:
wsl --manage <Distro> --resize <Size>
但“扩容”和“回收宿主空间”是两件事。扩容是让虚拟磁盘可用上限变大;回收是让 Windows 上的 VHDX 文件变小。
回收前先关掉 WSL:
wsl --shutdown
然后再按 Windows 版本和 WSL 版本选择方式。
有些环境可以依赖 WSL 的稀疏 VHD 支持,有些环境需要用 Optimize-VHD。Optimize-VHD 属于 Hyper-V 模块,不是所有 Windows 版本默认可用。
如果你能用:
Optimize-VHD -Path "C:\path\to\ext4.vhdx" -Mode Full
执行前一定确认路径是对应发行版的 VHDX,并且 WSL 已经 shutdown。
如果环境不支持这个命令,保守办法是导出/重新导入发行版:
wsl --export Ubuntu D:\backup\ubuntu.tar
wsl --unregister Ubuntu
wsl --import Ubuntu D:\WSL\Ubuntu D:\backup\ubuntu.tar --version 2
这条路风险更高,因为 --unregister 会删除原发行版。做之前必须确认导出文件可用、有备份、知道如何恢复。不要在半夜 C 盘 0 字节时第一次尝试。
给自己做一个巡检脚本
我会放一个 ~/bin/wsl-space-report:
#!/usr/bin/env bash
set -euo pipefail
echo "== filesystem =="
df -h /
echo
echo "== home top =="
du -h -d 1 "$HOME" 2>/dev/null | sort -h | tail -20
echo
echo "== work node_modules =="
fd -H '^node_modules$' "$HOME/work" -t d 2>/dev/null \
| xargs -r du -sh \
| sort -h \
| tail -20
echo
echo "== model caches =="
du -sh "$HOME/.cache/huggingface" "$HOME/.ollama" "$HOME/models" "$HOME/datasets" 2>/dev/null || true
echo
if command -v docker >/dev/null 2>&1; then
echo "== docker =="
docker system df || true
fi
加执行权限:
chmod +x ~/bin/wsl-space-report
每次 C 盘变红,先跑它。不要凭感觉删。
我自己的清理顺序
我的顺序通常是:
wsl-space-report找大头;- 清理 apt、Python、测试缓存;
- 清理废弃项目的
node_modules、.venv; docker system df -v看镜像和卷;- 删除不用的模型;
- 归档
~/runs和大数据集; wsl --shutdown;- 必要时压缩或迁移 VHDX。
不要反过来,一上来就压缩 VHDX。内部垃圾没清掉,压缩也没意义。
什么时候该重建一个干净发行版
如果一个 WSL 用了两三年,里面有无数项目、老版本语言运行时、废弃数据库、散落的模型和半残 Docker 卷,清理有时候不如重建。
做法是:
wsl --export Ubuntu D:\backup\ubuntu-old.tar
wsl --install -d Ubuntu
新发行版里只迁移:
~/work里仍在维护的项目;.ssh、.gnupg等明确需要的配置;- dotfiles;
- 必要的模型和数据;
- 脚本工具。
重建不是逃避,是把多年堆积的临时状态清掉。
小结
WSL 磁盘问题最容易让人误判,因为它有两层空间:
Linux 里面的空闲空间。
Windows 看到的 VHDX 文件大小。
清理要先在 Linux 里找到真正占用者,再决定删缓存、删依赖、删镜像、删模型还是迁移数据。内部清干净后,再考虑回收 VHDX。
不要把“C 盘满了”当成一个单点问题。它通常是开发习惯的结果:项目放哪、Docker 怎么用、模型缓存怎么管、归档有没有做。
参考资料: