どのアプリもメモリを使っていないのにも関わらず、メモリが枯渇することに遭遇したことはありませんか?それ、プールが大きくなっているかもしれませんよ。
プールってなに?
プール は、Windows のカーネルモードで動作するドライバー(Microsoft製以外のドライバーを含む)が、必要に応じて確保するメモリ領域になります。
プールの使用量は、タスクマネージャーのメモリタブで確認でき、プールの使用量が多い場合は、カーネルモードでメモリが使用されていると判断できます。
タスクマネージャーの表示からわかるように Windows のプールにはページプールと非ページプールの2種類があります。
1. ページプール (Paged Pool)
ページング可能なメモリ領域で、必要に応じてディスクにページアウトされることがあります。システムの動作に応じて必要なときに再び物理メモリへページインされます。
2. 非ページプール (Non-paged Pool)
これは物理メモリに常に保持され、ページアウトされないメモリ領域です。ページアウトが許されない、すぐにアクセスする必要がある重要なデータを保持します。
非ページプールの容量は有限で、上限は物理メモリのサイズにより決まります。システムの安定性に関わるため、非ページプールの使用量が増え物理メモリ不足になると、システムに重大な問題が発生します。
プールでメモリを確保するには?
ユーザーモードで動作するプロセスは、プールでメモリを確保することはできませんが、カーネルモードで動作するドライバーであれば、ExAllocatePoolWithTag 関数を使用してメモリを確保できます。なお、第一引数で非ページプールやページプールのどちらを使用するかは指定できます。
プールで発生する問題
一般的なメモリの問題であるメモリリークがあります。カーネルモードで確保したプールのメモリが使用後に正常に解放されないと、メモリリークが発生し、システム全体が不安定になることがあります。
特に非ページプールの上限は物理メモリに依存しているため、非ページプールでメモリリークが発生し、物理メモリが枯渇すると OS がハングすることがあります。
プロセスでのメモリリークが発生するとプロセスを強制終了することで、メモリを解放することができますが、プールでメモリリークが発生すると OS を再起動で解消する必要があります。
実際にページプールまたは非ページプールでメモリ使用量が多くなるとどのような問題が起きるかは、Microsoft が公開している NotMyFault ツールでテスト可能です。
NotMyFault ツールを起動し、Leak タブにある [Leak Paged] または [Leak Nonpaged] ボタンをクリックすると、1秒ごとに指定したメモリ量をページプールまたは非ページプールに確保して、メモリ リークを意図的に発生させられます。
さいごに
どのアプリもメモリを使用していないのに、メモリが枯渇している場合には、プールの使用量を確認してみてください。サイズが大きい場合は、いずれかのドライバーの不具合により、メモリリークが発生している可能性があります。
プールでメモリリークを発生させているドライバーは、WPR や WPA を使用して調査できます。調査方法については、別途投稿しようと思います。