タスクマネージャの "コミット済み" が無限に増え続ける

一難去ってまた一難だな。。
PCを使っているとタスクマネージャに表示される "コミット済み" 領域が増え続けて、最終的にはページファイルでSSDが埋まってクラッシュするようになった。
この領域はアプリケーションを全部閉じても減らないので、何かプロセス以外のところでリークが起きているように見える。

empty.exe
神話
日本語圏では一種の民間信仰として empty.exe
を使ったメモリ解放を行うことが行われている。今回のケースではこれは意味がなかった。 empty.exe
自体は既にMSからは配布されていないようだが、Rammapに同等の機能がある。
これらのEmptyは基本的に "メモリに置いておく必要が無いものを探し、その場で解放して空きメモリにする" 挙動になる。例えば実行中の .exe はHDDに元データがあるので一旦RAMから消して必要に応じて再ロードすることになる。

コミットチャージの中身
タスクマネージャの コミット済み は コミットチャージ / コミットリミット の表記となっている。今回増えている数字はWindows的にはコミットチャージ(Commit charge)と呼ばれる。
書籍Windows Internalsによると、コミットチャージの内容は:
- Private commited memory 。
VirtualAlloc
にCOMMIT
を渡している領域。要するに mmap 領域だな。 - Page-file-backed mapped memory 。ファイル以外を
MapViewOfFile
した領域。要するに anonymous mmap 領域だな。 - Copy-on-write regions of mapped memory 。要するにファイルの mmap 領域だな。
- ファイル以外の Nonpaged(スワップアウトできない) または Paged(スワップアウトできる) プール。いわゆるカーネルヒープ。
- カーネルスタック
- ページテーブル
- ページテーブル用の領域
- AWE(Address Windowing Extension) API用の物理メモリ
とりあえずパフォーマンスモニタでこの辺のパフォーマンスカウンタを観察してみるのが良いかな。
ここで Committed Bytes が今増えて困っているカウンタ。Pool Nonpaged Bytes、Pool Paged Bytes、Page File Bytes、Working Set - Privateを引くと2GBくらいの差になる。リークの確認時にこの差が広がっているならば、 RamMap の方に書かれているようなページテーブルやカーネルスタック等の影響と言える。

1Passwordのベータ版が原因だったっぽい
... なんで。。?
確かに仮想メモリの消費量は多いが。。ブラウザ連携のためにプロセス間通信をしていて、確かにブラウザから使えなくなっていたので怪しいといえば怪しい。さらに、Process Explorerで見てもVirtualがブラウザみたいに巨大になっている。
とにかく、1Passwordを終了させるとコミット済の量が増加しつづける現象は止まったように見える。
すげぇ量のハンドルだ。。システムのユーザプロセスのハンドルが合計35万くらいなので、半分以上が1Passwordが生成したハンドルって事になる。

1Password側が修正されたようだ
- We’ve fixed an issue that could prevent the app from connecting to the browser extension for some people.
#22451
- We’ve fixed an issue that could cause a memory leak in the app.
#22495