32GB Surface Pro 11 の常駐プロセスを WS で見たら指標を間違えた
2026-07-16 の Surface Pro 11 は、31.57GB の物理メモリのうち空きが2.53GBしかなかった(空き容量だけで犯人探しをしないためのメモだ)。
32GBあれば普段の作業では余るだろう、という感覚で使っていた。ところが Windows 11 Pro の上で Edge、Teams、OneDrive、Clawpilot、Docker Desktop、Google Drive、Notion まで立ち上げると、空きはかなり薄くなる。実行中サービスは149件、スタートアップ登録は18件。数字だけ見ると、いかにも常駐が犯人に見えるが、試した見方はそこまで単純では済まなかった(WS の足し算で説明しようとしたのが無理だった)。
ただ、今回いちばん間違えたのは「何を見るか」だった。Get-Process の WS を並べれば重い常駐が見えるはず、と思っていたが、実際にはその指標だけでは2.53GBしか空いていない理由を説明できなかった(ここに気づくまで、表の読み方をかなり誤っていた)。
WS順で見始めた
測ったのは、Get-Process のワーキングセット、実行中サービス数、スタートアップ登録、物理メモリ、CPU カウンタの5種類。マシンは Microsoft Surface Pro, 11th Edition、SoC は Snapdragon X 12-core X1E80100 @ 3.40GHz。OS は Windows 11 Pro 10.0.26200 の ARM64 版になる。
Get-Process |
Sort-Object WorkingSet64 -Descending |
Select-Object Name, Id, @{n="WS_MB";e={[math]::Round($_.WorkingSet64 / 1MB, 1)}}, CPU, Threads, Path
メモリは Win32_OperatingSystem の TotalVisibleMemorySize と FreePhysicalMemory を使った。値は KB なので、1024で2回割って GiB に直している。CPU は \Processor Information(_Total)\% Processor Performance、\% Processor Utility、\Processor Frequency を5サンプル拾った。
この時点では、WS_MB を足せばプロセスがどれだけ食っているかに近づくはず、という見立てで始めている。あとから見ると、そこが今回の失敗の入口だった。
ログに残った範囲の表
まず物理メモリは、TotalVisibleMemorySize が33,099,544KB、FreePhysicalMemory が2,650,072KB。GiB に直すと31.57GB中2.53GBが空きで、使われている側は差し引き29.04GBになる。
スタートアップ登録には ClawpilotTokenDashboard、PC Temp Monitor、Skill Control Center、Ueli、Teams、OneDrive、electron.app.Notion、Microsoft.Lists、electron.app.Clawpilot、GoogleDriveFS、Docker Desktop、SecurityHealth、iTunesHelper、GlobalSecureAccessClient が見えていた。重そうに見える名前はあるが、登録一覧だけで実メモリの大小まで決めるのは無理がある。
プロセス一覧は JSON の procs.stdout に入っていた。ただし、ここで大きな問題がある。stdout は20,000文字で切れており、ログ上で読める先頭がすでに WS_MB 8.1MB 付近から始まっていた。つまり、次の表は「ファイルに残っていた範囲の先頭15件」であって、厳密な全プロセス上位15件とは別物として読む必要がある。
| Name | PID | WS_MB | Threads | Path |
|---|---|---|---|---|
| cmd | 33500 | 8.1 | 2 | C:\Windows\system32\cmd.exe |
| cmd | 33816 | 8.1 | 2 | C:\Windows\system32\cmd.exe |
| cmd | 29920 | 8.1 | 2 | C:\Windows\system32\cmd.exe |
| SenseDlpProcessor | 2648 | 8.1 | 5 | |
| msedge | 15664 | 8.1 | 24 | C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe |
| cmd | 28048 | 8.1 | 2 | C:\Windows\system32\cmd.exe |
| cowork-svc | 8652 | 8.1 | 14 | |
| msedgewebview2 | 21272 | 8.0 | 9 | C:\Program Files (x86)\Microsoft\EdgeWebView\Application\151.0.4129.59\msedgewebview2.exe |
| msedgewebview2 | 7852 | 7.8 | 16 | C:\Program Files (x86)\Microsoft\EdgeWebView\Application\151.0.4129.59\msedgewebview2.exe |
| git | 39248 | 7.8 | 12 | C:\Users\akirasakai\AppData\Local\github-copilot-git-2.53.0-3\clangarm64\bin\git.exe |
| svchost | 4968 | 7.7 | 5 | |
| cmd | 53996 | 7.7 | 2 | C:\Windows\System32\cmd.exe |
| cmd | 35660 | 7.6 | 2 | C:\Windows\system32\cmd.exe |
| svchost | 11844 | 7.6 | 3 | |
| conhost | 32104 | 7.5 | 2 | C:\Windows\system32\conhost.exe |
この15件の合計は118.4MB、スレッド数の合計は102本。読める範囲の98プロセス全体では411.8MB、スレッド数は1,042本だった。上位5件だけなら40.5MBで、読める範囲の9.8%にとどまる。
表だけ見ると、cmd や conhost がやたら多い。Clawpilot や Node.js の周辺で小さなプロセスがたくさん残っていることも見える。とはいえ、2.53GBしか空いていない状況を、この表だけで説明するのは無理がある。
CPUカウンタも名前どおりには読めない
CPU 側も少しややこしかった。5サンプルの Processor Frequency は、1905MHz、1367MHz、1774MHz、1516MHz、1596MHz。平均は1631.6MHzで、公称の3.40GHzから見ると半分くらいに見えた。
アイドル寄りの状態で周波数が低く報告されること自体は納得できる。Surface Pro 11 が常に3.40GHzで回っている、という読み方はできなかった(なぜ合計が物理メモリとつながらないのか、後で疑えた)。ただ、同じタイミングの % Processor Performance は73.20%、74.62%、68.53%、63.50%、64.99%。% Processor Utility は55.996%、63.093%、41.019%、31.584%、31.524%だった。
このカウンタは、名前だけで読むと勘違いしやすい(実際に、最初はCPU使用率の仲間として読んでしまった)。なぜ同じ時刻の値なのに、周波数、性能比、Utility がここまで別々の顔をするのか。% Processor Performance は100%を超えることもある指標なので、単純なCPU使用率とは別のものとして扱う必要がある。今回は100%超えまでは出ていないが、周波数、性能比、Utility はそれぞれ別の顔だった。1つだけ抜き出すと、負荷の見え方を間違える。
WSを足す発想が壊れていた
今回の失敗は、ワーキングセットを足し算しようとしたこと(CPU カウンタ名を素直に読みすぎた)。JSON で読める98件を足しても411.8MBにとどまった。物理メモリ側では31.57GB中2.53GBしか空いていないので、差し引き29.04GBが使用側にある。数字がまったくつながらず、ここで測り方を疑うことになった。
原因は2つある。ひとつは、今回の procs.stdout が20,000文字で切れていて、大きいプロセスがログから落ちている点(プロセス単位よりアプリ単位で見たくなった)。もうひとつは、仮に完全な一覧を取れていても、ワーキングセットが共有メモリを重複して数える点(WS の足し算で説明しようとしたのが無理だった)。DLL や共有ページを複数プロセスが持っていれば、それぞれの WS_MB に見える。
つまり、ログ欠けがある今回は小さすぎる合計になった。完全なログでやり直すと、今度は共有分の重複で大きすぎる合計になるかもしれない(次は Private Working Set で取り直してみる)。どちらにしても、WS_MB の総和を「実メモリ使用量」と読むのはバグに近い。
測るなら、プライベートワーキングセットかコミット量を併せて取るべきだった。少なくとも Get-Process の WS だけで、常駐アプリを減らす優先順位を決めるのは危ない(ログ欠けと共有ページの二つを混ぜていた)。
次は指標を替える
この結果を見ても、すぐに常駐を減らす判断までは進めなかった(常駐削減の判断材料としては弱かった)。Docker Desktop、GoogleDriveFS、Teams、OneDrive、Clawpilot が重そうに見えるのは確かだが、今回の測り方では決定打としては弱い。犯人探しをするには、ログが欠けているうえ、指標の意味も足りていない、という痛い結果になった。
次に測るなら、Get-Process の WorkingSet64 に加えて、Private Working Set、Commit Size、プロセスツリー、同名プロセスのグルーピングを並べる。Edge や msedgewebview2 のようにプロセスを分けるアプリは、単体の行ではなくアプリ単位で見たい。これは次回への持ち越しの話。
2026年7月16日の時点で分かったのは、Surface Pro 11 の32GBが足りないというより、見ている数字の意味を取り違えると結論が簡単に曲がるということだった。常駐を削る前に、まず測る指標を選び直す。ここを先に直さないと、軽くしたつもりで何も変わらない、という結果になりそうな気がする。次は同じログを取り直してみて、Private Working Set と Commit Size を横に並べるつもりだ(WSだけで犯人探しをしないための保険)。