ターミナルで文字を打つのも、IMEの変換を確定するのも引っかかる。WSL2が激重になった時、あとで見たプロセス一覧にいたのはNeovimの子プロセス、Marksmanでした。CPUは約90%、RSS(Resident Set Size、常駐セットサイズ)は約5GiB。RSSはプロセスが使っている、スワップされていない物理メモリの量を表します。かなりの値です。
後から調べると、ホーム直下に空の .git がありました。設定メモを開く条件では、Marksmanがこれをrootの目印として拾い、ホーム全体をワークスペースにする経路を再現できました。高負荷時のroot値は残っていませんが、これが原因だったと私は判断しています。空の .git を削除し、Marksmanの起動範囲も絞った後は、メモリ使用量がかなり減りました。
.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のLSP
root_dir仕様 - nvim-lspconfigの移行説明
- LazyVimのMarkdown extra
ps(1)のRSS欄の説明(2026-09-24確認)
NeovimとLazyVimの公式情報は2026-09-27に確認し、公開前の2026-10-01に再確認しました。高負荷時のプロセス一覧、rootの再現、起動範囲の変更後の確認、9月27日のfree -hを根拠にしています。障害時のroot値、対処前後のMarksman RSS比較、Marksman単体のディスクI/Oは未記録です。

コメント