WSL2が激重に。ホームの空の.gitでMarksmanのrootが$HOMEになった

ターミナルで文字を打つのも、IMEの変換を確定するのも引っかかる。WSL2が激重になった時、あとで見たプロセス一覧にいたのはNeovimの子プロセス、Marksmanでした。CPUは約90%、RSS(Resident Set Size、常駐セットサイズ)は約5GiB。RSSはプロセスが使っている、スワップされていない物理メモリの量を表します。かなりの値です。

後から調べると、ホーム直下に空の .git がありました。設定メモを開く条件では、Marksmanがこれをrootの目印として拾い、ホーム全体をワークスペースにする経路を再現できました。高負荷時のroot値は残っていませんが、これが原因だったと私は判断しています。空の .git を削除し、Marksmanの起動範囲も絞った後は、メモリ使用量がかなり減りました。

高負荷時のWindowsとWSL内の別々の観測、後から再現したMarksmanのrootがホームになる経路、ホームならLSPを起動しない設定を分けた図。障害時のroot値と対処後RSSは未記録
後日の再現では、空の .git がMarksmanのrootをホームにしました。高負荷との関係はこの再現と対処後の変化から判断しています。Windows側の約10GBとWSL内の約5GiBは別の観測で、正確な前後比較ではありません。

WSL2が重い。終了後のプロセス一覧には何もいない

負荷に気づいた時、WindowsのタスクマネージャーにはCPU全体97%、VmmemWSLのメモリ約10GB、ディスク672MB/sと表示されていました。VmmemWSLはWSL2全体の表示です。ディスク値もWindows側の表示で、Marksman単体のI/Oではありません。

最初のプロセス調査は、Neovimと agy を閉じた後でした。CPU順・メモリ順に並べてもMarksmanはおらず、free -h も普通に見えます。

ps -eo pid,ppid,comm,%cpu,%mem,rss --sort=-%cpu | head -20
ps -eo pid,ppid,comm,%cpu,%mem,rss --sort=-rss | head -20
free -h

この時のメモリは合計11GiB、使用中674MiB、空き9.5GiB、利用可能11GiB、Swap使用2.1MiBでした。これは高負荷中の値ではありません。先にプロセスを終了してしまったので、原因を追う材料にはなりませんでした。

負荷が出ている時に、今度はプロセス一覧を30行まで出して取り直しました。

ps -eo pid,ppid,comm,%cpu,%mem,rss --sort=-%cpu | head -30
PID   PPID  COMMAND   %CPU  %MEM  RSS
3329  2979  marksman  89.5  33.1  4064968
3563  3416  agy       31.0   2.3   293692
2979  2978  nvim       2.0   0.3    48164

RSSの大きい順でも、Marksmanはさらに増えていました。

ps -eo pid,ppid,comm,%cpu,%mem,rss --sort=-rss | head -30
PID   PPID  COMMAND   %CPU  %MEM  RSS
3329  2979  marksman  91.7  42.7  5238212
3563  3416  agy       40.2   2.4   299612
2979  2978  nvim       1.8  0.4    51652

2回の記録では、MarksmanのRSSは4,064,968 KiBから5,238,212 KiBへ増加。psのRSS欄はKiB単位なので、約3.88GiBから約5.00GiBです(ps(1)の説明、2026-09-24確認)。PPIDはNeovimのPIDでした。agyも動いていましたが、MarksmanのCPUとメモリもかなり大きい。少なくとも、高負荷時に調べるべきプロセスとして浮かびました。

Windows側のVmmemWSL約10GBとこのRSS記録は、別々の観測です。同時刻だと確認できていません。プロセスを止めた後のfreeの値も、停止前後を同じ条件で比べた計測ではありません。したがって「Marksmanが何GB減らした」「これが10GBの内訳だった」とは書けません。

設定メモを開く条件では、ホームがMarksmanのrootになった

MarksmanはMarkdownの見出しやリンクを扱うLSPです。LazyVimのMarkdown extraを有効にすると、Marksmanも起動します。

高負荷時の起動条件を全部記録していなかったので、まずrootの決まり方を再現しました。そこで見つけたのが、ホームディレクトリ直下に空の .git ディレクトリがあったことです。作成経緯は分かりません。通常のGitコマンドはエラーになりましたが、Marksmanのroot探索では目印として扱われました。

設定メモの CHEATSHEET.md を開く条件を作り、Neovimをヘッドレスで実行すると、次の結果になりました。

Root for CHEATSHEET.md is: $HOME

この再現では、ホーム直下の空の .git がrootを $HOME にする直接の目印でした。障害時のroot値そのものは保存していません。.git の削除と起動範囲の制限を同時に行った後、メモリ使用量は大きく減りましたが、どちらがどれだけ効いたかは分かりません。

どのファイルを何件走査したかは記録していません。対処は、空の .git の削除と、rootがホームそのものならMarksmanを起動しないガードの設定です。

Marksmanは残して、起動する範囲を絞った

Marksmanを無効にする案もありました。けれど、markdownlint-cli2とは役割が違います。Marksmanはリンクや見出しなど文書構造を扱い、markdownlint-cli2は書式ルールを確認する。私の設定では両方を使っていたので、LSPを丸ごと外すより起動範囲を絞ることにしました。

まず、空であることを確認した上でホーム直下の .git を rmdir で削除しました。次にNeovimの設定で、.marksman.toml または .git が見つかった時だけMarksmanのrootとして許可し、rootがホームそのものなら起動しないようにしました。

以下はファイル全体ではなく、既存の return { … } にある neovim/nvim-lspconfig プラグイン指定の例です。ほかのプラグイン指定は残し、その中の opts.servers.marksman に置きます。

{
  "neovim/nvim-lspconfig",
  opts = {
    servers = {
      marksman = {
        root_dir = function(bufnr, on_dir)
          local root = vim.fs.root(bufnr, { ".marksman.toml", ".git" })
          if not root then
            return
          end

          local home = vim.uv.fs_realpath(vim.env.HOME or vim.env.USERPROFILE)
          local real_root = vim.uv.fs_realpath(root)
          if real_root == home then
            return
          end

          on_dir(root)
        end,
      },
    },
  },
},

許可できるrootが見つからない時やrootがホームと一致する時は、on_dir を呼ばずに戻ります。現行Neovimのroot_dirコールバックでは、これによりそのバッファでLSPを起動しません(Neovimのroot_dir仕様)。

手元のNeovimは0.12.1です。設定には single_file_support = false も残っていましたが、現行APIで単体ファイルの起動条件を抑えたのはこのroot_dirコールバックです。nvim-lspconfigの移行説明でも、現行APIでの設定方法が案内されています(移行説明)。

変更後は、ブログ記事を開くとMarksmanがアタッチし、単体ファイルではクライアント数が0のままでした。起動範囲を絞りつつ、記事を書く時のLSPは残せました。

ホームがrootになる経路を再現し、起動範囲を絞った

設定メモを開いた時に、ホーム直下の空の .git がMarksmanのrootを $HOME にする経路を再現できました。.git 自体がメモリを食ったわけではなく、ホーム全体をワークスペースにしたことが高負荷につながったと私は判断しています。空の .git を削除し、rootがホームなら起動しないガードを置いた後、私の環境ではメモリ使用量がかなり減りました。

2026年9月27日にWSLでfree -hを確認したところ、合計11GiBのうち使用中1.1GiB、利用可能10GiB、Swapは4.0GiB中3.0GiBでした。これはWSL全体の現在値です。約5GiBというMarksman単体のRSSと比べて削減量を出すことはできませんが、普段のメモリ使用量がかなり減ったことは実感しています。

確認した公式情報

NeovimとLazyVimの公式情報は2026-09-27に確認し、公開前の2026-10-01に再確認しました。高負荷時のプロセス一覧、rootの再現、起動範囲の変更後の確認、9月27日のfree -hを根拠にしています。障害時のroot値、対処前後のMarksman RSS比較、Marksman単体のディスクI/Oは未記録です。

コメント

タイトルとURLをコピーしました