mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
2223 字
6 分钟
WSL 最佳工作指南
2020-09-20

前言#

作为 WSL 的忠实用户,从 2019 年起我就用上了刚诞生的 WSL2。彼时的 WSL2 并不完美,在长期使用过程中曾遭遇以下痛点:

  • WSL1/2 转换和升级时失败,导致子系统内的全部文件丢失;
  • 开启/关闭 VPN 时可能连不上 WSL;
  • vmmem 占用资源奇高;
  • 磁盘空间不回收;

时至今日,微软已对 WSL 进行了大量改进。截至 2026 年,WSL 的最新稳定版本已达 2.7.0,内核基于 Linux 6.6 LTS,并引入了镜像网络、自动内存回收、Sparse VHD、Systemd 原生支持、USB 设备直通等一系列重磅特性。本文在原有基础上进行了全面更新,希望帮助大家打造更流畅的 WSL 工作环境。


一、关注 WSL 官方仓库,持续进行内核的更新#

1.1 使用 wsl --update 更新(推荐)#

WSL repo 中可以查阅大量已知问题。对于已修复的问题,只需在管理员权限的 PowerShell 中执行以下命令即可完成更新:

Terminal window
wsl --update
Tip

从 Windows 10/11 Store 版 WSL 起,内核更新已通过 Microsoft Store 自动下发,无需等待 Windows 系统更新推送,建议从 Store 安装 WSL 以保持最新版本。

1.2 手动编译内核更新#

如果需要开启内核中默认未启用的功能(例如 zswap 压缩内存交换),可以自行编译内核。主要有两个渠道:

渠道一:基于官方 WSL2 内核仓库

git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
cd WSL2-Linux-Kernel
make KCONFIG_CONFIG=Microsoft/config-wsl -j$(nproc)

渠道二:从 kernel.org 下载主线内核

kernel.org 下载内核源码,将 config-wsl 放入解压目录的 Microsoft/ 下,修改配置中的内核名称:

CONFIG_LOCALVERSION="-microsoft-wsl-custom"

然后执行编译:

make KCONFIG_CONFIG=Microsoft/config-wsl -j$(nproc)

WSL2 从内核 6.x 起,模块文件被单独存放在一个 modules.vhdx 文件中。若使用自定义内核,需要同时构建对应的 modules.vhdx,并在 .wslconfig 中通过 kernelModules 字段指定其路径,否则内核模块将无法正常加载。

编译完成后,将内核文件移至 Windows:

mv vmlinux /mnt/c/

修改 %USERPROFILE%\.wslconfig

[wsl2]
kernel=C:\\vmlinux
kernelModules=C:\\modules.vhdx

最后执行 wsl --shutdown 重启子系统,并通过 uname -r 确认内核版本。

若配置文件无效,也可将内核文件替换到 C:\Windows\System32\lxss\tools\kernel


二、详细配置 .wslconfig,全面优化性能#

按下 Win + R,输入 %UserProfile% 进入用户目录,创建或编辑 .wslconfig 文件。以下是截至 2026 年推荐的完整配置:

# 适用于所有 WSL2 发行版的全局配置
[wsl2]
# ── 资源限制 ──────────────────────────────────────────
# 限制 VM 最大内存用量(默认为系统内存的 50%)
memory=8GB
# 虚拟处理器核心数
processors=4
# 交换空间大小(默认为内存的 25%)
swap=4GB
# 自定义交换文件路径(可放到非系统盘)
# swapfile=D:\\wsl-swap.vhdx
# ── 网络配置 ──────────────────────────────────────────
# 网络模式:mirrored(镜像)是 Windows 11 22H2+ 的推荐模式
# 启用后 WSL 与 Windows 共享同一 IP,VPN 兼容性大幅改善
networkingMode=mirrored
# DNS 隧道(Windows 11 22H2+ 默认开启)
# 通过虚拟化特性解析 DNS,避免网络数据包冲突,改善 VPN 下的连接性
dnsTunneling=true
# 自动代理:自动同步 Windows 的 HTTP 代理设置到 WSL
autoProxy=true
# 传统 NAT 模式下的端口转发(mirrored 模式下此项被忽略)
localhostForwarding=true
# ── 功能开关 ──────────────────────────────────────────
# GUI 应用支持(WSLg),仅 Windows 11 支持
guiApplications=true
# 嵌套虚拟化(用于在 WSL 中运行 Docker daemon 等)
nestedVirtualization=true
# 调试控制台(显示 dmesg 输出,排查启动问题时开启)
# debugConsole=true
# ── 崩溃转储 ──────────────────────────────────────────
# 最大保留崩溃转储文件数
maxCrashDumpCount=3
[experimental]
# ── 内存自动回收 ──────────────────────────────────────
# gradual: CPU 空闲时逐步回收缓存内存;dropcache: 立即回收;disabled: 关闭
autoMemoryReclaim=gradual
# ── Sparse VHD(自动收缩虚拟磁盘)────────────────────
# 新建发行版将自动创建稀疏 VHD,可随文件删除自动缩小磁盘占用
sparseVhd=true
Note

mirrored 网络模式说明:传统 WSL2 使用 NAT 架构,每次启动 IP 都会变化,给端口映射和 VPN 带来诸多不便。镜像模式将 Windows 的网络接口直接映射到 Linux,WSL 与宿主机共享同一 IP,原生支持 IPv6 和组播,VPN 环境下的连通性也大幅改善。Windows 11 22H2 及更高版本均可使用。


三、配置 wsl.conf,精细控制单个发行版行为#

.wslconfig 是全局配置,而每个发行版内部的 /etc/wsl.conf 用于配置该发行版的特定行为。以下是推荐配置:

# /etc/wsl.conf(在 WSL 子系统内编辑)
[boot]
# 启用 Systemd(WSL 2022 年起原生支持)
# 启用后可正常使用 systemctl、journalctl 等服务管理命令
systemd=true
[automount]
# 自动挂载 Windows 驱动器
enabled=true
root=/mnt/
# metadata 元数据支持使 Linux 文件权限在 Windows 挂载点上生效
options="metadata,rw,umask=22,fmask=11"
mountFsTab=false
[network]
generateHosts=true
generateResolvConf=true
[interop]
# 允许从 WSL 启动 Windows 进程
enabled=true
# 将 Windows PATH 追加到 WSL 的 PATH 中
appendWindowsPath=true
[user]
# 指定默认登录用户
# default=yourname
Important

Systemd 的重要性:启用 systemd=true 后,Docker、snapd、cron、ssh 等依赖 systemd 的服务均可正常通过 systemctl 管理,这是在 WSL 中运行完整 Linux 服务栈的前提。


四、资源泄漏?关闭子系统 VM 强制回收内存#

若发现 vmmem 占用资源异常偏高,且当前并未在 WSL 中运行高负载进程,可按以下步骤处理:

方案一(推荐):启用 autoMemoryReclaim=gradual(见第 2 节 .wslconfig 配置),WSL 将在 CPU 空闲时自动回收缓存内存,从根本上缓解内存膨胀问题。

方案二:若问题已发生,直接强制停止 VM 实例:

Terminal window
wsl --shutdown

方案三:若能连入子系统,可用以下命令快速释放 Page Cache:

sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"

方案四(彻底排查):通过 htop 或以下命令定位具体的高占用进程:

# 按内存降序列出进程
ps aux --sort=-%mem | head -20

五、无法连接 WSL?“参考的对象类型不支持尝试的操作”#

使用 wsl 进入子系统时,有时会提示「参考的对象类型不支持尝试的操作」。这通常是代理软件(如 Clash、Proxifier)和 WSL2 的 Winsock 端口产生了冲突。

修复步骤(依次尝试)

Terminal window
# 步骤一:重置 Winsock 目录(需管理员权限)
netsh winsock reset
# 步骤二:若步骤一无效,重启 LxssManager 服务
# 注意:stop 命令是异步的,需等待数秒后再执行 start
net stop LxssManager
net start LxssManager

方案三(根治):使用 Proxifier 提供的 NoLsp.exe 工具,通过调用 WSCSetApplicationCategory WinAPI 阻止 Winsock LSP DLL 被加载到 wsl.exe 进程中:

Terminal window
NoLsp.exe C:\windows\system32\wsl.exe

此操作会在注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\AppId_Catalog 中为 wsl.exe 创建一个白名单条目,使 Windows 不再向 wsl.exe 注入 LSP DLL,一劳永逸。

方案四(2025+ 推荐):切换为 networkingMode=mirrored 网络模式,镜像模式从架构层面绕开了 NAT/Winsock 冲突问题,是最彻底的解决方案。


六、每次唤醒休眠后,CPU 占用奇高?#

可尝试以下几种方法:

  1. 使用 Win + Ctrl + Shift + B 重新绘制屏幕;
  2. 更新 WSL 内核到最新版本(参考第 1 节);
  3. .wslconfig 中开启 autoMemoryReclaim=gradual,减少唤醒后的内存压力;
  4. 具体问题可参考 WSL GitHub Issue #6982

七、磁盘空间不回收的问题(Sparse VHD 新方案)#

在子系统中执行 du -h --max-depth=1 / 检查实际磁盘占用后,若发现虚拟磁盘文件(ext4.vhdx)体积远大于实际数据,可通过以下三种方案解决:

7.1 方案一:启用 Sparse VHD(推荐,一劳永逸)#

.wslconfig 中添加:

[experimental]
sparseVhd=true

对于已有的发行版,执行以下命令将其转换为稀疏 VHD:

Terminal window
wsl --manage <发行版名称> --set-sparse true

启用后,VHD 文件会随着文件删除自动缩减,无需再手动压缩。

7.2 方案二:手动压缩虚拟磁盘(适用于旧版本)#

Terminal window
wsl --shutdown
diskpart
# 在 DiskPart 窗口中执行:
# VHD 路径一般为:
# C:\Users\<用户名>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu...\LocalState\ext4.vhdx
select vdisk file="C:\...\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit

方案三:迁移虚拟磁盘到其他驱动器#

若 C 盘空间紧张,可使用 move-wsl 工具将虚拟磁盘迁移至其他磁盘,或使用原生命令:

Terminal window
# 导出发行版
wsl --export Ubuntu D:\WSL\ubuntu-backup.tar
# 注销原发行版(会删除原数据,请确保已备份)
wsl --unregister Ubuntu
# 在新位置重新导入
wsl --import Ubuntu D:\WSL\Ubuntu D:\WSL\ubuntu-backup.tar --version 2
Warning

数据无价,执行 --unregister 操作前务必先 --export 备份!该操作会删除发行版内的所有数据,且不可恢复。


八、备份与还原:wsl —export / —import#

这是 WSL 最容易被忽视却极为重要的功能。定期备份可避免系统崩溃、WSL 升级失败等导致的数据丢失(正如前言中提到的惨痛经历)。

Terminal window
# 查看当前安装的所有发行版
wsl --list --verbose
# 导出发行版(打包为 tar 文件)
wsl --export Ubuntu D:\WSL-Backup\ubuntu-$(Get-Date -Format "yyyyMMdd").tar
# 还原发行版(从 tar 文件导入)
wsl --import Ubuntu-Restored D:\WSL\Ubuntu D:\WSL-Backup\ubuntu-20260101.tar --version 2
# 指定还原后的默认用户(在子系统内执行)
# 编辑 /etc/wsl.conf,添加:
# [user]
# default=yourusername

自动化备份脚本(PowerShell)

Terminal window
# 保存为 wsl-backup.ps1,可配合任务计划程序定期执行
$backupDir = "D:\WSL-Backup"
$date = Get-Date -Format "yyyyMMdd_HHmm"
$distro = "Ubuntu"
if (-not (Test-Path $backupDir)) { New-Item -ItemType Directory -Path $backupDir }
Write-Host "正在备份 $distro ..."
wsl --export $distro "$backupDir\$distro-$date.tar"
Write-Host "备份完成:$backupDir\$distro-$date.tar"
# 只保留最近 5 个备份
Get-ChildItem "$backupDir\$distro-*.tar" |
Sort-Object LastWriteTime -Descending |
Select-Object -Skip 5 |
Remove-Item -Force

九、USB 设备直通:usbipd-win#

WSL2 默认不支持 USB 设备访问,但通过开源项目 usbipd-win 可将 Windows 上的 USB 设备共享给 WSL2 使用,对嵌入式开发(Arduino、ESP32、STM32 等)极为实用。

9.1 安装#

Windows 端(管理员 PowerShell):

Terminal window
winget install --interactive --exact dorssel.usbipd-win

WSL Linux 端:

sudo apt install linux-tools-generic hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip \
/usr/lib/linux-tools/*-generic/usbip 20

9.2 使用流程#

Terminal window
# 1. 列出所有 USB 设备(Windows 端,管理员权限)
usbipd list
# 2. 绑定设备(首次操作,需管理员权限,绑定状态在重启后保持)
usbipd bind --busid 4-4
# 3. 挂载设备到 WSL(无需管理员权限)
usbipd attach --wsl --busid 4-4
# 4. 在 WSL 中验证
# lsusb
# 5. 卸载设备
usbipd detach --busid 4-4

9.3 常见问题#

问题:防火墙阻断(TCP 3240 端口)

usbipd 使用 TCP 3240 端口通信。若出现连接被拒,可尝试:

Terminal window
# 将网络连接类型改为「专用网络」
Set-NetConnectionProfile -InterfaceAlias "以太网" -NetworkCategory Private

问题:设备权限不足

在 WSL 中为设备添加 udev 规则:

# 例如为 STM32 开发板添加规则
echo 'ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE="0666"' | \
sudo tee /etc/udev/rules.d/99-stlink.rules
sudo udevadm control --reload
Note

mirrored 网络模式的兼容性:在镜像网络模式下,需要在 WSL 内通过 sudo usbip attach -r localhost --busid=4-1 的方式连接,而非标准的 usbipd attach --wsl


十、WSLg:在 WSL 中运行 Linux GUI 应用#

Windows 11 原生支持通过 WSLg(Windows Subsystem for Linux GUI)运行 Linux 图形界面程序,无需安装 X Server。

.wslconfig 中确保开启:

[wsl2]
guiApplications=true

然后在 WSL 中直接安装并运行 GUI 程序:

# 安装示例:gedit 文本编辑器
sudo apt install gedit -y
gedit &
# 安装 Firefox
sudo apt install firefox -y
firefox &

应用程序会以原生窗口的形式出现在 Windows 桌面,并在任务栏中显示图标。


十一、开发环境最佳实践#

11.1 文件系统性能建议#

WSL2 对 Linux 文件系统(/home)的 I/O 性能远优于跨文件系统访问(/mnt/c/)。建议:

  • 代码仓库:存放在 WSL 的 Linux 文件系统内(~/projects/),而非 /mnt/c/
  • 共享文件:确实需要 Windows 和 WSL 共用时,再放到 /mnt/c/
  • 可在 Windows 中通过 \\wsl$\Ubuntu\home\用户名\projects 访问 WSL 内的文件。

11.2 Windows Terminal 配置#

推荐使用 Windows Terminal 作为终端,支持标签页、分屏和 Quake 模式(Win + `` “)。在 settings.json 中可为 WSL 配置启动目录:

{
"startingDirectory": "//wsl$/Ubuntu/home/yourusername"
}

11.3 VS Code 集成#

安装 VS Code 的 WSL 扩展,可在 WSL 环境中无缝编辑文件:

# 在 WSL 中,直接用 code 命令打开当前目录
code .

十二、Reference#


参考#

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

WSL 最佳工作指南
https://blog.souloss.com/posts/tools/wsl-best-work-guide/
作者
Souloss
发布于
2020-09-20
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时