web-dev-qa-db-ja.com

ページ違反の原因は何ですか?

ウィキペディアによると

ページフォールトは、プログラムが仮想アドレス空間にマップされているが物理メモリにロードされていないページにアクセスするときにハードウェアによって発生するソフトウェアへのトラップです。 (エンファシス鉱山)

さて、それは理にかなっています。

しかし、その場合、Process Hackerのプロセス情報が更新されるたびに、約15ページのフォールトが表示されるのはなぜですか?

Screenshot

または、言い換えると、メモリがページアウトされるのはなぜですか? (ユーザーまたはカーネルメモリかどうかはわかりません。)noページファイルと、RAM使用法クリーンリブート後の4 GBのうち約1.2 GBです。リソースが不足することはありません。なぜページアウトされるのでしょうか。

25
Mehrdad

(私はProcess Hackerの著者です。)

まず:

ページフォールトは、プログラムが仮想アドレス空間にマップされているが物理メモリにロードされていないページにアクセスしたときに、ハードウェアによって発生したソフトウェアへのトラップです。

同じ記事で後述するように、これは完全に正しいわけではありません(マイナーページフォールト)。ソフトページフォールトがあり、カーネルが行う必要があるのは、プロセスのワーキングセットにページを追加することだけです。これは、Windows Internalsブックの表です(アクセス違反につながるものは除外しました)。

  • 障害の理由-結果
  • メモリには存在しないが、ページファイルまたはマッピングファイルでディスク上にあるページにアクセスする-物理ページを割り当て、ディスクから関連するワーキングセットに目的のページを読み込む
  • スタンバイリストまたは変更済みリストにあるページへのアクセス-関連するプロセス、セッション、またはシステムワーキングセットへのページの移行
  • デマンドゼロページへのアクセス-関連するワーキングセットにゼロで埋められたページを追加します
  • コピーオンライトページへの書き込み-ページのプロセスプライベート(またはセッションプライベート)コピーを作成し、プロセス内またはシステムワーキングセットのオリジナルを置き換えます

上記のように、ページフォールトはさまざまな理由で発生する可能性があります。それらの1つだけがディスクからの読み取りに関係しています。ヒープからブロックを割り当てようとして、ヒープマネージャーが新しいページを割り当ててからそれらのページにアクセスすると、デマンドゼロのページフォールトが発生します。 kernel32のページに書き込むことによってkernel32の関数をフックしようとすると、それらのページがサイレントコピーされるため、変更が他のプロセスに影響を与えないため、コピーオンライトフォールトが発生します。

ここで、より具体的に質問に答えましょう。ProcessHackerは、サービス情報を更新するときにのみページフォールトがあるようです。つまり、 EnumServicesStatusEx を呼び出し、SCM(services.exe)にRPCします。私の推測では、プロセス中に大量のメモリが割り当てられており、デマンドゼロのページフォールトが発生しています(IIRCでは、サービス情報を保存するには複数のページが必要です)。

39
wj32

ページフォールトの遅いが安定した原因は、アクセス頻度の低いページのOSプローブです。この場合、オペレーティングシステムは存在しないページをマークしますが、メモリ内にはそのまま残します。アプリケーションがページにアクセスすると、#PFトラップが発生し、OSは単に面倒なことなく、存在するページを再びマークします。 「長時間」が経過し、ページがフォールトを決してトリップしない場合、OSは、そのページが必要に応じてスワッピングの適切な候補であることを認識します。このメカニズムは、リソースが圧迫されていない場合でもプロアクティブに実行できます。

5
srking

「仮想アドレス空間にマッピングされているが、物理メモリにロードされていないページ」は、以前に物理メモリにあったことを意味するものではありません。ファイルをマッピングするとしますか?まだメモリ内ではなく、ディスク上にあります。

ログファイルをマップし、追加し続けるとします。コミットされたメモリの終わりを超えるたびにページフォールトが発生し、OSは新しい空のページを提供し、ファイルの長さを調整します。


また、プログラムによってキャッチおよび処理されるアクセス違反の可能性もあります。


また、プログラムがTLB(ページテーブルのキャッシュ)に収まるよりも多くのメモリセグメントを使用する可能性もあります。ページが連続している場合、それらはすべて単一のページテーブルエントリで処理できます。しかし、メモリが物理アドレス空間で断片化されている場合、多くのページテーブルエントリが必要になり、TLBに収まらない場合があります。 TLBミスが発生すると、OSページフォールトハンドラーが呼び出され、プロセスのページテーブルでマッピングを検索します。

いくつかの点で、これは Deanの答え のバリエーションです。ページは既に物理RAMにあり、OSはIPCのためではなく、TLBにそれらのマッピングをロードする必要があります。

ブライアンは、x86(およびすべてのWin32システム)がページフォールトなしでこれを処理することを指摘しました。


ページフォールトのさらに別の原因は、スタックの拡大とコピーオンライトに使用されるガードページのトリガーですが、通常、それらは無制限に発生しません。これらがアクセス違反として表示されるかどうかは、100%わからない。なぜなら、これらはMMUトラップへのエントリでアクセス違反としてマークされるが、おそらくOSによって処理されるためページフォールトハンドラーおよびユーザーモード(SEH)アクセス違反に変換されません。

4
Ben Voigt

Mmapされたセクションが読み取られるたびに、ページフォールトが生成されます。これには、DLLを読み込むたびが含まれます。したがって、DLLをロードしても、実際にすべてのDLLがメモリに読み込まれるわけではありません。コードが実行されるときにエラーが発生するだけです。

2
Ana Betts

プロセス間でメモリが共有されている場合、soft page faultsが表示されます。基本的に、2つのプロセス間で共有されるメモリマップファイルがある場合、2番目のプロセスがメモリマップファイルをロードすると、ソフトページフォールトが生成されます-メモリは既に物理RAMにありますが、オペレーティングシステムはメモリを修正する必要がありますプロセスの仮想メモリアドレスが正しい物理ページを指すように、マネージャーのテーブル。

特に、(情報を収集するために)実行中のすべてのプロセスにコードを挿入する可能性が高いProcess Hackerのようなものでは、IPCを実行するために共有メモリをかなり大量に使用している可能性があります。

1
Dean Harding

オペレーティングシステムはページングを使用してアイテムをグループ化し、物理メモリに配置して物理メモリと共有メモリ間で移動する必要があります。ほとんどの場合、単一のページに配置されるデータ項目は互いに関連しています。ページ内のデータ項目が長時間使用されない場合、オペレーティングシステムはそれを仮想メモリに移動して、物理メモリの一部の領域を解放します。そして、ページが必要な場合、魔女が仮想メモリ内にあると、オペレーティングシステムはそのページを仮想メモリ(ハードディスク)から物理メモリに移動します。これはページフォルトです!

また、異なるオペレーティングシステムはページングアルゴリズムが異なることを忘れないでください。

ページフォールトの基礎

0
Farzin Zaker

リソースの割り当ては、プライマリストレージを使用可能な状態に保つことと、できる限りセカンダリストレージに移動する必要を防ぐこととの微妙なバランスです。プロセスがメモリを割り当てようとしてもできない場合、通常は例外であり、場合によっては致命的な例外です。

基本的に、プログラムを起動したり、さらに要求するとクラッシュするため、利用可能な空きリソースがない状態でRAMにすべてを保持することはできません。

0
Bacon Bits