# VmmemWSL 内存占用高，先查任务再回收

`VmmemWSL` 在任务管理器中代表 WSL 虚拟机环境使用的资源。其内存可能包括活跃的 Linux 工作负载和缓存。如果 Docker、AI 模型服务器或开发工具在那里运行，关闭 Windows 编辑器不一定能停止那项工作。

首先确定内存属于正在运行的任务，还是任务结束后仍保留的缓存。删除 WSL 虚拟磁盘不是内存修复方法，可能破坏 Linux 环境及其数据。

## 查找 WSL 内的工作负载

从 PowerShell 检查已安装的环境：

```
wsl --version
wsl --list --verbose
wsl --list --running
```

在相关 Linux 发行版内，使用这些只读视图：

```
free -h
ps -eo pid,comm,rss --sort=-rss
```

Linux 的读数与任务管理器的 VM 总量范围不完全相同。用它们定位进程并区分可用内存与文件缓存，而不是强求每个数字完全吻合。对于 Docker 中运行的任务，检查 Docker Desktop 的运行容器，并通过其正常控制停止预期任务。

AI 服务器可能在回答后仍保持模型加载。如果不再需要该工作负载，通过模型服务的正常方式停止它。不要仅仅因为进程名称不熟悉就随意终止它。

## 阅读 Linux 内存样本，不把每一份缓存都当作泄漏

在 `free -h` 的输出中，既要注意 `available`，也要注意 `used` 和 `buff/cache`。Linux 会把原本空闲的内存用于文件数据，其中一部分在应用程序需要时可以回收。因此，仅凭一个较小的 `free` 值，不足以断定 Linux 内存已经耗尽。

进程列表以 KiB 报告 RSS，而 `free -h` 使用人类可读单位。共享页和 VM 开销也意味着，把各进程行相加不一定等于任务管理器中的 VmmemWSL 数值。用最大的几行确定占用者，再检查相应的工作负载，不要强行让总数一致。

如果涉及 Docker，以下只读命令可列出正在运行的容器并采集一次资源样本，参见 [Docker stats 参考](https://docs.docker.com/reference/cli/docker/container/stats/)：

```powershell
docker ps
docker stats --no-stream
```

在与被调查的 Docker 后端相连的环境中运行这些命令。不同的 Docker 上下文可能指向远程机器，因此操作前先确认目标。容器显示的内存数值与整个 WSL VM 总量范围不同。

对比三种状态：AI 任务启动前、运行中，以及应用程序正常卸载模型或停止任务之后。如果大进程仍然存活，缓存回收不能代替判断该进程是否应继续运行。如果进程缩小但缓存仍在，回收行为就成了更相关的问题。

## 检查当前回收设置

Microsoft 的 [WSL 配置参考](https://learn.microsoft.com/en-us/windows/wsl/wsl-config) 将全局 WSL 2 设置放在 `%USERPROFILE%\.wslconfig` 中。它不同于发行版内的 `/etc/wsl.conf`。

当前参考在 `[experimental]` 下列出 `autoMemoryReclaim`，其默认值为 `dropCache`，另一种支持的模式为 `gradual`。因此，声称这个选项默认关闭、必须手动开启的旧建议可能已经过时。在添加任何内容之前，检查已安装的 WSL 版本和现有配置。

如果已安装的版本支持这个设置，而且你希望逐步回收缓存，将此条目合并到现有文件中：

```
[experimental]
autoMemoryReclaim=gradual
```

不要覆盖无关设置或创建重复的配置节。这改变缓存内存的回收方式，不会让活跃模型或数据库需要更少内存。在决定是否保留更改前，比较相同工作负载。

## 修改现有配置并保留回退路径

在文件资源管理器中打开 `%USERPROFILE%`，在创建或编辑 `.wslconfig` 之前启用文件扩展名。误存为 `.wslconfig.txt` 的文件并不是想要的配置。先把现有配置复制为备份，并保留与内存无关的配置段。

在一个现有 `[experimental]` 配置段下，只改动正在测试的回收项。只有在不存在配置且确实需要更改设置时，才需要新建文件。不要同时添加 `dropCache` 和 `gradual` 两行，也不要在从不同文章复制示例后重复该配置段。

Microsoft 记录的默认值本就会回收缓存。将其改为 `gradual` 是一次策略实验，并非总能节省更多内存的升级。它可能让缓存驻留得比立即回收更久。如果当前行为没有表现出问题，就保留默认值，转而调查活动工作负载。

通过安全的 WSL 重启应用更改后，再次运行同一任务，观察 Windows 操作是否流畅、Linux 可用内存以及任务是否完成。如果更改没有帮助，从备份恢复先前的条目，再以同样的先保存后重启的预防措施应用该恢复。不要为了移除一行实验性配置就删除整个配置文件。

## 仅在保存工作后重启 WSL

配置更改在 WSL 环境重启时生效。Microsoft 的 [基本命令](https://learn.microsoft.com/en-us/windows/wsl/basic-commands) 记录了全局关闭命令：

```
wsl --shutdown
```

使用前，保存文件，停止训练或推理任务，并正常关闭受影响的容器或数据库。该命令停止所有运行中的发行版和 WSL 2 VM，包括 Docker Desktop 背后的工作。它会关闭整个环境，不能只回收其中一部分内存。

如果关闭后 VmmemWSL 内存消失，只能说明这部分内存来自刚刚关闭的环境。它不能区分泄漏与活跃任务或有用缓存。重启所需服务，在相同工作完成后比较。

## 将按任务需求设置内存上限

`.wslconfig` 的 `memory` 设置限制 WSL 2 的可用内存。上限太低可能导致 Linux 应用程序失败或大量交换。程序需要的内存不会因此变少。仅在测量工作负载和 Windows 也需要的 RAM 后选择它，然后确认应用仍能完成任务。

Docker Desktop 的 [WSL 指南](https://docs.docker.com/desktop/features/wsl/) 讨论了其 WSL 后端的内存回收。使用 WSL 后端对应的配置，而不是应用无关的 Hyper-V 指令。

## 确认内存上限确实已生效

如果需要上限，在现有配置的 `[wsl2]` 下放置 `memory`。例如，`memory=8GB` 表示 8 GB 的限制，而不是为每个发行版保留 8 GB。这是语法示例，不是每台电脑的推荐预算。多个 WSL 2 发行版共享全局 VM 预算，选择上限时要算上它们同时进行的工作。

保存工作并重启 WSL 后，在某个发行版内检查 `free -h` 报告的总量，并与预期上限比较，同时考虑系统开销。然后运行实际的模型或构建。如果 Linux 任务现在被杀死或把时间花在交换上，任务管理器数值变小并不算成功。

如果限制似乎被忽略，检查拥有该文件的 Windows 账户、文件扩展名、目标发行版是否为 WSL 2，以及旧 VM 是否已完全停止。这些检查比反复调低数值更有信息量。不要把关闭交换作为同时进行的第二个实验，因为这会改变工作负载达到预算时的行为。

对于 Docker 工作负载，保持 Docker 正常的关闭和数据持久化行为不变。关闭终端不一定停止其容器，而全局关闭 WSL 可能中断多个无关服务。在应用 VM 级更改前，通过各应用自身的控制保存数据库和训练工作。

## 将 RAM 与虚拟磁盘空间分开

| 问题 | 相关调查 |
| --- | --- |
| AI 任务运行时内存上升 | 模型、上下文和并发 Linux 工作 |
| 工作结束后缓存保留 | 回收行为和 WSL 版本 |
| 整个 PC 面临压力 | Windows 内存和提交 |
| WSL 磁盘文件保持很大 | 文件和虚拟磁盘存储，而非 RAM |

[Windows 内存指南](/zh/windows/blog/windows-high-memory-usage) 涵盖主机端读数。对于磁盘容量，使用单独的 [Docker 和 WSL 存储指南](/zh/windows/blog/docker-wsl-disk-space-windows)。永远不要将 `wsl --unregister` 用作清理捷径：它删除发行版及其数据，而不是解决高内存读数。


Canonical: https://mole.fit/zh/windows/blog/vmmemwsl-high-memory
