メモリの保護
プロセスに属するメモリは、プライベート仮想アドレス空間によって暗黙的に保護されます。 さらに、Windows は仮想メモリ ハードウェアを使用してメモリ保護を提供します。 この保護の実装はプロセッサによって異なります。たとえば、プロセスのアドレス空間内のコード ページを読み取り専用としてマークし、ユーザー モード スレッドによる変更から保護できます。
属性の完全な一覧については、「 メモリ保護定数」を参照してください。
書き込み時のコピー保護
書き込み時のコピー保護は、プロセスの 1 つがページを変更するまで、複数のプロセスが物理ページを共有するように仮想アドレス空間をマップできるようにする最適化です。 これは レイジー評価と呼ばれる手法の一部であり、システムは絶対に必要になるまで操作を実行しないことで物理メモリと時間を節約できます。
たとえば、2 つのプロセスが同じ DLL から仮想メモリ空間にページを読み込むとします。 これらの仮想メモリ ページは、両方のプロセスで同じ物理メモリ ページにマップされます。 どちらのプロセスもこれらのページに書き込む限り、次の図に示すように、同じ物理ページにマップして共有できます。
プロセス 1 がこれらのページのいずれかに書き込む場合、物理ページの内容が別の物理ページにコピーされ、プロセス 1 の仮想メモリ マップが更新されます。 どちらのプロセスも、物理メモリ内のページの独自のインスタンスを持つようになりました。 そのため、あるプロセスが共有物理ページに書き込み、もう一方のプロセスで変更を確認することはできません。
アプリケーションと DLL の読み込み
同じ Windows ベースのアプリケーションの複数のインスタンスが読み込まれると、各インスタンスは、独自の保護された仮想アドレス空間で実行されます。 ただし、インスタンス ハンドル (hInstance) は通常、同じ値を持ちます。 この値は、仮想アドレス空間内のアプリケーションのベース アドレスを表します。 各インスタンスを既定のベース アドレスに読み込むことができる場合は、書き込み時のコピー保護を使用して、同じ物理ページを他のインスタンスにマップして共有できます。 システムでは、いずれかのインスタンスがページを変更するまで、これらのインスタンスで同じ物理ページを共有できます。 何らかの理由で、これらのインスタンスの 1 つを目的のベース アドレスに読み込むことができない場合は、独自の物理ページを受け取ります。
DLL は、既定のベース アドレスで作成されます。 DLL を使用するすべてのプロセスは、DLL の既定の仮想アドレスにある独自のアドレス空間内に DLL を読み込もうとします。 複数のアプリケーションが既定の仮想アドレスで DLL を読み込むことができる場合は、DLL に対して同じ物理ページを共有できます。 何らかの理由で、プロセスが既定のアドレスで DLL を読み込むことができない場合は、DLL を別の場所に読み込みます。 ジャンプ命令の修正プログラムは DLL のページ内に書き込まれ、このプロセスでは異なるため、書き込み時のコピー保護により、DLL のページの一部が異なる物理ページに強制的にコピーされます。 コード セクションにデータ セクションへの参照が多数含まれている場合は、コード セクション全体が新しい物理ページにコピーされる可能性があります。