301 Moved Permanently

Moved to https://vow.g.hatena.ne.jp/vow/

最近の一言

empty.exe はアプリケーションのメモリ管理の不備に対してアプリケーション自身にとっての緩和策にはなり得ない

(続き)

なんか妙に流行っぽいですけれど、どう考えても説明がおかしいのでちょろっとだけ。


empty.exeWindows用語で言うところのワーキングセットを一時的にゼロにするものです。なんだか魔法の言葉っぽく聞こえるかもしれませんが、もう少し一般的な用語で説明すると、プロセスのユーザモードの論理アドレス空間にマッピングされている物理メモリをほぼ全てアンマップする、となります。

じゃあそのアンマップってのが解放なんじゃないの? と思うかもしれませんがこれは全く別の概念で、所謂メモリ領域の解放とはほぼ何の関係もありません。ではアンマップとはなんぞやというと、プロセスの占有していたメモリをプロセス自身から「すぐに使える状態」では無いようにする、ということになります。それは解放されてるってことじゃないの? と思うかもしれませんが大違いで、それが証拠にプロセスが当該の領域を再び使用しようとしたとたんに復活します。もし本当に解放していたら復活するものがありません。

これは要するにスワップの機構であって、つまり放っておいてもシステム側で普段から勝手に行っている処理です。empty.exe がしているのはシステムが自動的に行う以上の範囲でスワップアウトを“促進する”というだけで、何ら特別なことはありません。よって・・・

  • 元々スワップの対象にならない領域は empty.exe してもスワップの対象にはなりません。
  • 元々スワップの対象になりうる領域は empty.exe しなくてもスワップの対象になる可能性があります。
  • あるメモリ領域が「すぐに使える状態」で無くなっても、それが実際にスワップアウトされるという保証はありません。
  • プロセスの論理アドレス空間の配置とその内容には何の変動も起こしません。というか勝手に変えたらバグです、暴走です。
  • プロセスから見た「確保済みメモリ」の配置は変わりません。同じ事ですが「空きメモリ」の配置も変わりません。
  • プロセスから見た「新たに追加で確保できるメモリの量」、つまり大雑把な意味での空きメモリ量は変わりません。

要するにプロセスから見たメモリの確保状況には一切何の変化ももたらしません。ですので仮に当該のプロセスが何らかのメモリ管理の不備を抱えているとして、empty.exe してもその不備の結果は何の影響も受けずにそのまま残ります。まるっきりそのままです。


そこまで何の意味もない empty.exe ってそれならいったい何なのさ、という話になるかと思いますが、はっきり言いまして標的にされたプロセス自身のメモリ管理としては何の意味もありません。あくまでシステム全体の仮想メモリ管理としてスワップの順序に影響するだけです。

ただし一つ注意すべき事があって、プロセスが「すぐに使える状態」では無いメモリを使おうとした際には、そのメモリを「すぐに使える状態」に戻すためにページフォルトなる処理が起動します。これは当然システム側で用意されているもので、放っておけば必要に応じてスワップインを行い、物理ページへのマッピングを追加した上で“何事も無かったかのように”元の処理に戻ります。プロセスの実行そのものは原則としてメモリがすぐに使えた場合でもすぐに使えなかった場合でも同じように進行しますが、実際にはすぐに使えなかった場合ページフォルトで道草を食った分の時間はどうしてもかかっていますので、タイミングにはズレが生じます。またシステム側で行われるページフォルト処理の前後に追加で余計なことをするように仕込むことは可能であって、場合によって何事かの副作用を起こす (あるいは起きてしまう) ことはあり得ます。

そうしたタイミングのズレや何らかの副作用がなにがしかの異なる動作に結びつくことは十分に考えられます。・・・が、それは作用機序からしてメモリ管理の問題ではありませんで、平たく言って何か別のバグです。


まあそういうわけなので、実運用環境において empty.exe が何らかの効果を発揮する可能性を一概に否定するわけではありませんが、少なくともそれは「メモリ管理の不備の緩和」によって成し遂げられているわけでは無く、何かもっと迂遠な因果によるものであろうと思われます。

なお私の環境ではそもそもゾーン失敗なんて滅多に起きた試しがないので追試もくそもへったくれもありません。うん、コケるほど高性能な機械は使ってないんだよ・・・。