前言
作为 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 中执行以下命令即可完成更新:
wsl --update从 Windows 10/11 Store 版 WSL 起,内核更新已通过 Microsoft Store 自动下发,无需等待 Windows 系统更新推送,建议从 Store 安装 WSL 以保持最新版本。
1.2 手动编译内核更新
如果需要开启内核中默认未启用的功能(例如 zswap 压缩内存交换),可以自行编译内核。主要有两个渠道:
渠道一:基于官方 WSL2 内核仓库
git clone https://github.com/microsoft/WSL2-Linux-Kernel.gitcd WSL2-Linux-Kernelmake 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:\\vmlinuxkernelModules=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 代理设置到 WSLautoProxy=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=truemirrored 网络模式说明:传统 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=trueroot=/mnt/# metadata 元数据支持使 Linux 文件权限在 Windows 挂载点上生效options="metadata,rw,umask=22,fmask=11"mountFsTab=false
[network]generateHosts=truegenerateResolvConf=true
[interop]# 允许从 WSL 启动 Windows 进程enabled=true# 将 Windows PATH 追加到 WSL 的 PATH 中appendWindowsPath=true
[user]# 指定默认登录用户# default=yournameSystemd 的重要性:启用 systemd=true 后,Docker、snapd、cron、ssh 等依赖 systemd 的服务均可正常通过 systemctl 管理,这是在 WSL 中运行完整 Linux 服务栈的前提。
四、资源泄漏?关闭子系统 VM 强制回收内存
若发现 vmmem 占用资源异常偏高,且当前并未在 WSL 中运行高负载进程,可按以下步骤处理:
方案一(推荐):启用 autoMemoryReclaim=gradual(见第 2 节 .wslconfig 配置),WSL 将在 CPU 空闲时自动回收缓存内存,从根本上缓解内存膨胀问题。
方案二:若问题已发生,直接强制停止 VM 实例:
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 端口产生了冲突。
修复步骤(依次尝试):
# 步骤一:重置 Winsock 目录(需管理员权限)netsh winsock reset
# 步骤二:若步骤一无效,重启 LxssManager 服务# 注意:stop 命令是异步的,需等待数秒后再执行 startnet stop LxssManagernet start LxssManager方案三(根治):使用 Proxifier 提供的 NoLsp.exe 工具,通过调用 WSCSetApplicationCategory WinAPI 阻止 Winsock LSP DLL 被加载到 wsl.exe 进程中:
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 占用奇高?
可尝试以下几种方法:
- 使用
Win + Ctrl + Shift + B重新绘制屏幕; - 更新 WSL 内核到最新版本(参考第 1 节);
- 在
.wslconfig中开启autoMemoryReclaim=gradual,减少唤醒后的内存压力; - 具体问题可参考 WSL GitHub Issue #6982。
七、磁盘空间不回收的问题(Sparse VHD 新方案)
在子系统中执行 du -h --max-depth=1 / 检查实际磁盘占用后,若发现虚拟磁盘文件(ext4.vhdx)体积远大于实际数据,可通过以下三种方案解决:
7.1 方案一:启用 Sparse VHD(推荐,一劳永逸)
在 .wslconfig 中添加:
[experimental]sparseVhd=true对于已有的发行版,执行以下命令将其转换为稀疏 VHD:
wsl --manage <发行版名称> --set-sparse true启用后,VHD 文件会随着文件删除自动缩减,无需再手动压缩。
7.2 方案二:手动压缩虚拟磁盘(适用于旧版本)
wsl --shutdowndiskpart# 在 DiskPart 窗口中执行:# VHD 路径一般为:# C:\Users\<用户名>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu...\LocalState\ext4.vhdxselect vdisk file="C:\...\ext4.vhdx"attach vdisk readonlycompact vdiskdetach vdiskexit方案三:迁移虚拟磁盘到其他驱动器
若 C 盘空间紧张,可使用 move-wsl 工具将虚拟磁盘迁移至其他磁盘,或使用原生命令:
# 导出发行版wsl --export Ubuntu D:\WSL\ubuntu-backup.tar
# 注销原发行版(会删除原数据,请确保已备份)wsl --unregister Ubuntu
# 在新位置重新导入wsl --import Ubuntu D:\WSL\Ubuntu D:\WSL\ubuntu-backup.tar --version 2数据无价,执行 --unregister 操作前务必先 --export 备份!该操作会删除发行版内的所有数据,且不可恢复。
八、备份与还原:wsl —export / —import
这是 WSL 最容易被忽视却极为重要的功能。定期备份可避免系统崩溃、WSL 升级失败等导致的数据丢失(正如前言中提到的惨痛经历)。
# 查看当前安装的所有发行版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):
# 保存为 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):
winget install --interactive --exact dorssel.usbipd-win在 WSL Linux 端:
sudo apt install linux-tools-generic hwdatasudo update-alternatives --install /usr/local/bin/usbip usbip \ /usr/lib/linux-tools/*-generic/usbip 209.2 使用流程
# 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-49.3 常见问题
问题:防火墙阻断(TCP 3240 端口)
usbipd 使用 TCP 3240 端口通信。若出现连接被拒,可尝试:
# 将网络连接类型改为「专用网络」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.rulessudo udevadm control --reload与 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 -ygedit &
# 安装 Firefoxsudo apt install firefox -yfirefox &应用程序会以原生窗口的形式出现在 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 官方仓库
- WSL 配置文档
- WSL 网络配置
- WSL2-Linux-Kernel
- kernel.org
- usbipd-win(USB 设备直通)
- connect-usb 官方文档
- move-wsl(虚拟磁盘迁移)
- wsl.dev 社区资源
- NoLsp.exe 原始下载链接
- zswap in WSL2 优化指南
参考
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






