web-dev-qa-db-ja.com

Windows 10でメモリ/コミットチャージはどのように機能しますか?

この質問は、私が説明を見つけたい次の定期的に観察される現象によって促されます。

  1. 現在のコミットは、物理的な使用量+ページファイルのサイズよりも定期的に高くなっています。どうしたの?それは不可能ではないでしょうか? [これは圧縮が原因である可能性があります。これは、質問を次のように変換します。なぜ制限をコミットせずに上がらないのですか?つまりメモリ使用量に役立たない場合の圧縮のポイントは何ですか?]
  2. 時々これは極端なレベルに達し、現在のコミットは物理メモリ使用量の2倍以上です!
  3. コミットチャージがいっぱいになり、ウィンドウが閉じを要求するようになると、ほとんどの場合、物理メモリは約60%です。これはひどく非効率的なようです。

これは、ProcessExplorerによって報告されたWindows10にあります。

私が回答したい最終的な質問は、ページファイルを人為的にインフレートしてスペース不足のSSDが処理するのに不十分なレベルにまで見越して、実際に物理メモリを実際に活用できるようにすることはできますか? (または、それがいっぱいでなかったとしても。つまり、「ページファイルに対してX/Y/Zを実行する」のような提案は避けたいです。)

4
martixy

コミット料金が潜在的-それでも「必要に応じて利用可能であることが保証されている」-仮想メモリの使用であり、「プライベートワーキングセット」-本質的にRAMは「コミットされた」メモリで使用されます-is actual use、as pagefile space。 (ただし、RAMを使用するものは他にもあるため、これがRAMの使用のすべてではありません)。

32ビットシステムについて話していると仮定しましょう。したがって、各プロセスで使用できる最大仮想アドレス空間は通常2GiBです。 (64ビットシステムの場合、次のanyに実質的な違いはありませんが、アドレスとサイズが大きくなる可能性があります-はるかに大きくなります。)

ここで、プロセスで実行されているプログラムがVirtualAlloc(Win32 API)を使用して2MiBの仮想メモリを「コミット」するとします。ご想像のとおり、これは追加の2 MiBのコミットチャージとして表示され、将来の割り当てのためにプロセスで使用できる仮想アドレス空間は2 MiB少なくなります。

ただし、実際にはまだ物理メモリ(RAM)を使用しません。

VirtualAlloc呼び出しは、割り当てられた領域の開始アドレスを呼び出し元に返します。領域は0x10000から0x7FFEFFFFの範囲、つまり約2GiBになります。 (各プロセスのv.a.s.の最初と最後の64KiB、または16進数で0x10000が割り当てられることはありません。)

しかし、繰り返しになりますが、実際の物理的な2 MiBのstorageはまだ使用されていません。 RAMにも、ページファイルにもありません。 (「仮想アドレス記述子」と呼ばれる小さな構造があり、開始v.a.とプライベートコミット領域の長さを記述します。)

だからあなたはそれを持っています!コミットチャージは増加しましたが、物理メモリの使用量は増加していません。

これは、sysinternalsツールtestlimitを使用して簡単に説明できます。

しばらくして、プログラムがその領域に何か(つまり、メモリ書き込み操作)を格納するとします(どこでもかまいません)。どの領域の下にもまだ物理メモリがないため、このようなアクセスではページフォールトが発生します。これに応じて、OSのメモリマネージャー、具体的にはページフォールトハンドラルーチン(略して「ページャー」... MiAccessFaultと呼ばれます)は次のようになります。

  1. 以前に「利用可能な」物理ページを割り当てる
  2. アクセスされた仮想ページのページテーブルエントリを設定して、仮想ページ番号を新しく割り当てられた物理ページ番号に関連付けます
  3. 物理ページをプロセスプライベートに追加しますワーキングセット
  4. ページフォールトを閉じて、フォールトを発生させた命令を再試行します。

これで、プロセスに1ページ(4 KiB)の「障害」が発生しました。それに応じて物理メモリの使用量が増加し、「使用可能」RAMが減少します。コミット料は変わりません。

しばらくして、そのページがしばらく参照されておらず、RAMの需要が高い場合、次のことが発生する可能性があります。

  1. oSは、プロセスワーキングセットからページを削除します。
  2. ワーキングセットに取り込まれてから書き込まれたため、変更されたページリストに配置されます(そうでない場合、スタンバイページリストに配置されます)。ページテーブルエントリはRAMのページの物理ページ番号を反映していますが、「有効」ビットがクリアされているため、次に参照されたときにページフォールトが発生します。
  3. 変更されたページリストが小さなしきい値に達すると、「システム」プロセスの変更されたページライタースレッドがウェイクアップし、変更されたページのコンテンツをページファイルに保存します(ある場合)。 ..
  4. それらのページを変更済みリストから削除し、スタンバイリストに配置します。これらは現在、「使用可能な」RAMの一部と見なされています。しかし、今のところ、それぞれのプロセスにあったときのオリジナルのコンテンツがまだ残っています。繰り返しになりますが、コミット料金は変更されませんが、RAMの使用量とプロセスのプライベートワーキングセットはダウンします。
  5. スタンバイリストのページを再利用にすることができます。つまり、システム上の任意のプロセスからのページフォールトの解決や、SuperFetchでの使用など、他の目的で使用できます。しかしながら...
  6. 変更リストまたはスタンバイリストでページを失ったプロセスが、物理ページが再利用される前に(つまり、元のコンテンツがまだ残っている)そのページに再度アクセスしようとすると、ディスクから読み取らずにページフォールトが解決されます。ページは単にプロセスワーキングセットに戻され、ページテーブルエントリが「有効」になります。これは、「ソフト」または「安価な」ページ違反の例です。スタンバイリストと変更されたリストは、システム全体のページキャッシュを形成し、すぐに再び必要になる可能性が高いと言えます。

ページファイルがない場合は、手順3〜5が次のように変更されます。

  1. 内容を書き込む場所がないため、ページは変更されたリストに載っています。

  2. 内容を書き込む場所がないため、ページは変更されたリストに載っています。

  3. 内容を書き込む場所がないため、ページは変更されたリストに載っています。

変更されたリストのページは、「ソフト」ページフォールトとして失われたプロセスにフォールトバックされる可能性があるため、ステップ6は同じままです。ただし、それが発生しない場合は、プロセスが対応する仮想メモリの割り当てを解除するまで(おそらくプロセスが終了するため)、ページは変更されたリストに残ります。

プライベートコミットメモリの他に、仮想アドレス空間とRAMの使用法があります。 mapped仮想アドレス空間があり、バッキングストアはページファイルではなく指定されたファイルです。マップされたv.a.sのページページインされたものはRAMの使用量に反映されますが、マップされたファイルはバッキングストアを提供するため、マップされたメモリはコミットチャージに寄与しません。RAMにないマップされた領域の部分は単純ですマップされたファイルに保持されます。もう1つの違いは、ほとんどのファイルマッピングをプロセス間で共有できることです。あるプロセスですでにメモリ内にある共有ページは、ディスクに再度移動することなく別のプロセスに追加できます(別のソフトページフォールト)。

そして、nonpageable v.a.s.がありますが、これは常にRAMに常駐しているため、バッキングストアはありません。これは、報告されたRAMの使用量と「コミット料金」の両方に影響します。

これは圧縮が原因のようです。これは、質問を次のように変換します。なぜ制限をコミットせずに上がらないのですか?つまりメモリ使用量に役立たない場合の圧縮のポイントは何ですか?

いいえ。圧縮とは関係ありません。 Windowsのメモリ圧縮は、中間ステップとして、ページファイルに書き込まれるページで行われます。事実上、変更されたページリストはより少ないRAMを使用してより多くのものを含めることができますが、CPU時間は多少犠牲になりますが、ページファイルI/Oよりもはるかに高速です(SSDに対しても) 。コミット制限はtotal RAM +ページファイルサイズで計算され、RAM使用量+ページファイル使用量ではないため、これはコミット制限に影響しません。コミット制限は、RAMの使用量や使用目的によって変わりません。

コミットチャージがいっぱいになり、ウィンドウが閉じを要求するようになると、ほとんどの場合、物理メモリは約60%です。これはひどく非効率的なようです。

Windowsが非効率的であるということではありません。実行しているアプリです。彼らはもっと多くのv.a.sをコミットしています。彼らが実際に使用しているよりも。

"commit charge"と "commit limit"メカニズム全体の理由は次のとおりです。VirtualAllocを呼び出すとき、戻り値をチェックしてゼロでないかどうかを確認することになっています。ゼロの場合は、割り当ての試行が失敗したことを意味します。これは、コミットチャージがコミット制限を超えたためと考えられます。コミットを減らしたり、プログラムをきれいに終了したりするなど、妥当なことをすることになっています。

VirtualAllocがゼロ以外の値、つまりアドレスを返した場合、システムが保証を行ったことを通知します-コミットした場合、そのアドレスから始めて、私が要求したバイト数になります利用可能それらにアクセスすることを選択した場合。 RAMまたはページファイルのいずれか-すべてを配置する場所があること。つまり、そのリージョン内の何かにアクセスする際に何らかの失敗を予期する理由はありません。 「うまくいったか」をチェックすることを期待するのは合理的ではないので、それは良いことです。割り当てられたリージョンへのすべてのアクセス。

「現金貸付銀行」の例え

これは、クレジットを提供する銀行に少し似ていますが、厳密には手元現金ベースです。 (もちろん、これは実際の銀行の仕組みではありません。)

銀行が手持ちの百万ドルの現金で始まると仮定します。人々は銀行に行き、さまざまな金額のクレジットラインを要求します。銀行が$ 100,000のクレジットラインを承認したとします(私はプライベートコミットリージョンを作成します)。それは、現金が実際に金庫から出たという意味ではありません。後で実際にたとえば20,000ドル(この地域のサブセットにアクセスします)のローンを借りると、銀行から現金が取り除かれます。

しかし、私が融資をするかどうかに関係なく、私が最大10万ドルで承認されたという事実は、銀行がその後すべての顧客に対して合計でさらに90万ドル相当の信用枠しか承認できないことを意味します。銀行は、現金準備を超えるクレジットを承認しません(つまり、承認しませんオーバーコミットそれら)。これは、銀行が以前に承認した借り手を後で表示するときに拒否しなければならない可能性があるためです。持ち帰るつもりで彼らローン。銀行はすでにコミット済みこれらのローンを許可しているので、それは非常に悪いことであり、銀行の評判は急落するでしょう。

はい、これは銀行がその現金を使用するという点で「非効率的」です。また、顧客が承認する与信枠と実際に融資する金額との差が大きいほど、効率は低下します。しかし、その非効率性は銀行の責任ではありません。これは、このような高い信用枠を要求するが、少額のローンしか引き受けないという顧客の「欠点」です。

銀行のビジネスモデルは、以前に承認された借り手がローンを取得するために現れたときに、それを断ることはできないということです-そうすることは顧客にとって「致命的」になります。そのため、銀行はローン資金の「コミット」額を注意深く追跡しています。

ページファイルを拡張したり、別のページファイルを追加したりすることは、銀行が外に出て現金を増やし、それをローン基金に追加するようなものだと思います。

このアナロジーでマップされた非ページメモリをモデル化したい場合...非ページは、アカウントを開いたときに持ち出して差し控えなければならない小さなローンのようなものです。 (新しい各プロセスを定義するページング不可能な構造。)マップされたメモリは、自分の現金(マップされているファイル)を持ってきて銀行に預け、一度にその一部だけを取り出す(ページングする)ようなものです。一度にすべてをページインしてみませんか?わからない。たぶん、財布の中に現金が入る余地がないのかもしれません。 :)これは、他の人がお金を借りる能力に影響を与えません。預金した現金は、一般的なローン資金ではなく、自分の口座にあるからです。このアナロジーは、特に共有メモリについて考え始めたときに、そこで崩壊し始めます。したがって、あまりプッシュしないでください。

Windows OSに戻る:RAMの「使用可能」の多くがあるという事実は、コミット料金やコミット制限とは何の関係もありません。コミット制限に近づいている場合は、OSがすでにコミットされていることを意味します。つまり、要求されたときに利用可能にすることを約束-大量のストレージ。制限を適用するために、まだすべてが使用中である必要はありません。

物理メモリを実際に効果的に利用できるようにするために、スペース不足のSSDを処理するための設備が整っていないレベルまで、ページファイルを人為的に膨らませるのをやめることはできますか? (または、それがいっぱいでなかったとしても。つまり、「ページファイルに対してX/Y/Zを実行する」のような提案は避けたいです。)

申し訳ありませんが、コミット制限に達した場合、実行できることは3つだけです。

  1. RAMを増やします。
  2. ページファイルのサイズを大きくします。
  3. 一度に実行するものが少なくなります。

オプション2に関して:ハードドライブに2番目のページファイルを置くことができます。アプリが実際にコミットされたメモリをすべて使用していない場合(明らかに使用されていないため、空き容量が非常に多いためRAM)、実際にはそのページファイルにあまりアクセスしないため、ハードに配置します。ドライブはパフォーマンスを損なうことはありません。ハードドライブの速度がまだ気になる場合は、別のオプションとして、小型で安価な2番目のSSDを入手し、その上に2番目のページファイルを配置します。 1つの「ショーストッパー」は、2番目の「リムーバブルでない」ドライブを追加する方法がないラップトップです。 (Windowsでは、USBに接続されているもののように、取り外し可能なドライブにページファイルを配置することはできません。)

これが 私が書いた別の答え 別の方向から物事を説明しています。

pS:Windows 10について質問しましたが、NTファミリーのすべてのバージョン、NT 3.1、およびプレリリースバージョンでも同じように機能することをお伝えしておきます。変更された可能性が高いのは、ページファイルサイズのWindowsのデフォルト設定であり、1.5倍または1倍RAMサイズからはるかに小さいサイズになっています。これは間違いだったと思います。

9
Jamie Hanrahan