Codex作業後にPowerShellが残ってメモリを食った話:プロセス掃除まで運用に入れる

実験ログ

Codexでブログ運用を進めている最中、タスクマネージャーを見たらメモリ使用率が90%を超えたままになっていました。最初は「WordPressに長文記事を保存したから一時的に重いのかな」くらいに思っていましたが、しばらく待っても下がりません。

確認してみると、原因はCodexそのものではなく、タイムアウトしたPowerShellプロセスが残っていたことでした。WordPress REST APIへの下書き保存でタイムアウトした処理が、終了しきらずに残り、1本あたり数百MBから約1GB近くのメモリを使っていました。

これは見逃すと地味に危ないです。すぐにPCが壊れる、寿命が何年縮む、というような断定はできません。ただ、不要なプロセスが残ったままメモリやCPUを使い続けると、PCが重くなり、発熱しやすくなり、作業効率も落ちます。ノートPCならファンが回りっぱなしになることもあります。結果として、快適に使える状態を保ちにくくなります。

そこで今回は、Codexで自動化作業をした後に、PowerShellなどの残留プロセスを確認し、必要なものだけ止める運用を作りました。この記事は、その実験ログです。

結論:作業後の掃除まで運用に入れる

今回の結論はシンプルです。

  • APIタイムアウト後は、プロセスが残っていないか確認する
  • Codex本体は基本的に止めない
  • WordPressやThreads連携で使ったPowerShellだけを対象にする
  • いきなり停止せず、まずDryRunのように候補を確認する
  • 問題なければ掃除スクリプトで停止する

今回追加したのは、scripts/cleanup-stale-powershell.ps1 という掃除スクリプトです。通常実行では止める候補を見るだけで、-Kill を付けた時だけ実際に停止します。

powershell -ExecutionPolicy Bypass -File scripts/cleanup-stale-powershell.ps1
powershell -ExecutionPolicy Bypass -File scripts/cleanup-stale-powershell.ps1 -Kill

この「まず見る、次に止める」という二段階にしたのがポイントです。プロセス停止は便利ですが、雑にやると必要なアプリまで落とす可能性があります。掃除も自動化するなら、安全弁が必要です。

何が起きていたのか

この日の作業では、Threads APIの記事を作成し、WordPressへ下書き保存していました。本文は5000字以上で、参考URLも含む長めの記事です。最初は既存のWordPress保存スクリプトでREST APIへJSON形式のPOSTを送りました。

ところが、WordPress側の応答が返ってこず、コマンドがタイムアウトしました。さらに、再試行した処理もタイムアウトしました。

その後、WordPress側を確認すると、下書き自体は作られていました。ただし本文は仮文のまま。つまり、最初の作成処理は途中まで成功し、長文本文更新のところで詰まっていた状態です。

ここまではWordPress REST APIの問題として整理できます。しかし、別の問題が残っていました。タイムアウトしたPowerShellプロセスが、Windows上に残っていたのです。

実際に確認すると、次のようなPowerShellプロセスが残っていました。

  • save-wp-draft.ps1 の残留プロセスが2本
  • update-wp-draft-content.ps1 の残留プロセスが2本
  • それぞれが数百MBから約1GB近くのメモリを使用

これが積み重なって、メモリ使用率が高止まりしていました。処理は失敗したように見えても、プロセスが完全に消えているとは限らない。ここが今回の学びです。

Codexが9個あるのは異常なのか

タスクマネージャーを見ると、Codexのプロセスも複数ありました。数としては9個ほど見えていました。

最初はこれも怪しく見えます。しかし、確認してみると、CodexはElectron/Chromium系のアプリとして動いており、内部的に複数プロセスへ分かれていました。

  • メインプロセス
  • GPUプロセス
  • 画面表示用のrendererプロセス
  • network service
  • storage service
  • crashpad handler
  • codex.exe app-server

つまり、Codexが複数見えること自体は、すぐ異常とは言えません。実際、ブラウザやElectron系アプリでは、タブや描画、GPU、ネットワークなどを分けて動かすことがあります。

今回の問題は、Codex本体よりも、APIタイムアウト後に残っていたPowerShellでした。Codexプロセスをむやみに止めると、作業中のセッションや画面状態が壊れる可能性があります。なので、掃除対象はCodex本体ではなく、残留した作業用PowerShellに絞ることにしました。

まず確認したコマンド

最初にやったのは、PowerShellプロセスの一覧確認です。

Get-Process |
  Where-Object { $_.ProcessName -match 'powershell|pwsh' } |
  Select-Object Id,ProcessName,CPU,WorkingSet64,StartTime,Path |
  Sort-Object WorkingSet64 -Descending

これで、どのPowerShellがどれくらいメモリを使っているかを確認しました。WorkingSet64 は、そのプロセスが使っている物理メモリ量の目安として見られます。

次に、どのコマンドで起動されたPowerShellなのかを確認しました。

Get-CimInstance Win32_Process |
  Where-Object { $_.Name -match 'powershell|pwsh' } |
  Select-Object ProcessId,Name,CommandLine

この確認で、残っていたプロセスが save-wp-draft.ps1update-wp-draft-content.ps1 由来だと分かりました。つまり、Codex本体ではなく、WordPress更新のタイムアウト処理が残っていたわけです。

Microsoftのドキュメントでも、Windowsには実行中のプロセス一覧を表示する tasklist コマンドが用意されています。また、PowerShellでは Stop-Process でプロセスを停止できます。ただし、Microsoftの Stop-Process の説明にもある通り、プロセス停止は影響範囲に注意が必要です。止めるプロセスは、名前だけでなくPIDやコマンドラインを見て判断した方が安全です。

実際に止めたもの

今回、メモリを大きく使っていたPowerShellは、WordPress保存でタイムアウトしたものだと分かりました。そこで、対象PIDを指定して停止しました。

Stop-Process -Id 21928,22640,21956,18700 -Force

停止直後は、プロセス一覧にまだ見えているものもありました。これは終了処理中のような状態だったため、数秒待って再確認しました。その後、該当プロセスは消えました。

ここで大事なのは、「重そうだからPowerShellを全部止める」としなかったことです。PowerShellの中には、Codexや開発環境が使っているものもあります。全部まとめて止めると、別の作業まで壊す可能性があります。

今回は、コマンドラインを見て、明らかにこのプロジェクトのWordPress更新スクリプト由来のものだけを止めました。

掃除スクリプトを作った

毎回手で確認してPIDを指定するのは面倒です。そこで、プロジェクト用に掃除スクリプトを作りました。

ファイル名は次です。

scripts/cleanup-stale-powershell.ps1

このスクリプトは、次の条件で候補を探します。

  • PowerShellまたはpwshのプロセスである
  • このプロジェクト配下の作業コマンドである
  • 既知の運用スクリプト名を含んでいる
  • 一定時間以上動いている、または一定以上のメモリを使っている

対象にしたスクリプト名は、たとえば以下です。

  • save-wp-draft.ps1
  • update-wp-draft-content.ps1
  • update-wp-draft-meta.ps1
  • check-wp-draft-by-slug.ps1
  • publish-threads-post.ps1
  • check-threads-token.ps1

通常実行では、候補を表示するだけです。

powershell -ExecutionPolicy Bypass -File scripts/cleanup-stale-powershell.ps1

停止まで行う時だけ、-Kill を付けます。

powershell -ExecutionPolicy Bypass -File scripts/cleanup-stale-powershell.ps1 -Kill

この設計にした理由は、誤停止を避けるためです。プロセス掃除は便利ですが、間違えると必要な作業まで落とします。だから、Threads投稿の時に DryRun を入れたのと同じように、プロセス掃除にも「まず確認」を入れました。

PCの寿命について、言いすぎない

今回の話をすると、「メモリ90%超えはPCの寿命を縮めるのでは」と不安になるかもしれません。

ここは少し冷静に見たいところです。メモリ使用率が高いだけで、すぐにPCが壊れるとは言えません。Windowsはメモリをキャッシュや圧縮にも使いますし、タスクマネージャーの数字だけで寿命を断定するのは乱暴です。

ただし、不要なプロセスが残り続けて、CPUやメモリを使い続ける状態はよくありません。PCが重くなり、ファンが回り、発熱しやすくなることがあります。発熱や高負荷状態が長く続けば、部品への負担やバッテリーの消耗につながる可能性はあります。

だから、この記事で言いたいのは「メモリ90%だからすぐ危険」という話ではありません。「自動化した作業の後始末まで含めて運用に入れよう」という話です。

SE視点:失敗時の後片付けまで設計する

SE視点で見ると、今回のポイントは「正常系だけでなく異常系の後片付け」です。

API連携や自動化スクリプトを作る時、つい成功時の処理に意識が向きます。投稿できるか。保存できるか。トークンが通るか。もちろんそれも大事です。

しかし、実運用では失敗時の方が重要です。タイムアウトした時、途中まで作成された下書きはどう扱うのか。再実行して重複しないか。残ったプロセスは消えるのか。ログは残るのか。

今回、WordPress下書き保存でタイムアウトした後、同じ処理をそのまま再実行すると重複下書きや残留プロセスのリスクがありました。そこで、先に slug で既存下書きを確認し、既存投稿IDに対して本文とメタ情報を分けて更新する方針にしました。

さらに、タイムアウト後はPowerShellの残留を確認するチェックも追加しました。これは地味ですが、運用としてはかなり効きます。

PT視点:作業環境の負荷も体に返ってくる

理学療法士の視点を少し入れるなら、PCの重さは作業姿勢や疲労にもつながります。

PCが重いと、待ち時間が増えます。待っている間に姿勢が崩れたり、イライラして作業が雑になったりします。ファンが回りっぱなしだと、音も気になります。こうした小さなストレスが積み重なると、集中力も落ちます。

身体のケアでは、痛くなってから対処するより、負担が増えにくい環境を作ることが大切です。PC作業も同じで、重くなってから慌てるより、作業後に残留プロセスを確認する習慣を作る方が楽です。

もちろん、プロセス掃除だけで肩こりや疲労が解決するわけではありません。ただ、作業環境の小さなストレスを減らすことは、長くデスクワークを続ける上で意味があります。

農・生活視点:道具は使った後に片付ける

畑作業で使った道具は、使い終わったら片付けます。ハサミを出しっぱなしにしない。ホースを踏まないところに戻す。刃物は汚れを落とす。そうしないと、次に使う時に困ります。

PC作業も似ています。自動化スクリプトを走らせたら、結果だけでなく、後片付けも見る。プロセスが残っていないか。ログは残ったか。次回同じ失敗をしないメモはあるか。

半農エンジニアラボでは、こういう小さな運用改善も「生活を整える実験」として扱います。畑もPCも、使った後の片付けまで含めて道具です。

運用ルールに残したこと

今回の件は、その場で終わらせず、プロジェクトのMarkdownにも残しました。

  • docs/runtime-rules.md:PowerShellプロセス掃除の運用ルールを追加
  • docs/operation-checklist.md:WordPressタイムアウト時のチェックに掃除項目を追加
  • docs/wordpress-rest-api-save-flow.md:JSON更新タイムアウト時の回避策を追記

これで、次回のCodex作業でも「前に何で詰まったか」を見返せます。チャットが変わっても、プロジェクト側のルールとして残るのが大事です。

今後の改善

今回の掃除スクリプトは、まだ第一歩です。今後は次のような改善が考えられます。

  • WordPress保存処理の最後に、自動で掃除候補チェックを走らせる
  • タイムアウトした時だけ掃除チェックを促す
  • メモリ使用量の推移をログに残す
  • 停止したプロセスIDと理由をログに記録する
  • Codex本体や通常アプリを誤って止めない保護条件をさらに強くする

ただし、掃除の自動化は慎重に進めます。止める処理は、作る処理より危険です。最初は候補表示だけ、次に手動で -Kill。このくらいの段階を踏むのがちょうどよいと感じています。

まとめ

今回は、Codex作業後にPowerShellが残ってメモリを大きく使っていた問題をきっかけに、プロセス掃除まで運用に入れました。

分かったことは、Codexプロセスが複数あること自体は必ずしも異常ではない、ということです。Electron/Chromium系アプリでは、GPU、renderer、network、storageなどで複数プロセスに分かれることがあります。

一方で、タイムアウトしたPowerShellが残り続け、メモリを大きく使う状態は放置したくありません。今回のように、コマンドラインを確認し、このプロジェクトの作業スクリプト由来のものだけを止める運用が現実的です。

自動化は、動かすところだけ作って終わりではありません。失敗した時にどう止まるか。途中まで成功したものをどう確認するか。残ったプロセスをどう片付けるか。そこまで含めて、ようやく運用になります。

PCを長く快適に使うためにも、そしてブログ運用を気持ちよく続けるためにも、これからは「作業後の掃除」までセットで回していきます。

参考URL