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


3

この質問は、私が説明したいのですが、定期的に観察される以下の現象によって促されます。

  1. 現在のコミットは通常、物理使用量+ページファイルサイズよりも大きくなっています。どうしたの?それは不可能ではないでしょうか。 [これは圧縮のせいかもしれません。これは質問を変容させる:なぜコミット制限が上がらないのか、それとも何かなのか?すなわちメモリの使用に役立たない場合、圧縮のポイントは何ですか?]
  2. 現在のコミットが物理メモリ使用量の2倍以上になる極端なレベルに達することがあります。
  3. コミット料金がいっぱいになり、Windowsが物事を閉じるように私に頼み始めたとき、ほとんどの場合物理メモリは約60%です。これは非常に非効率的です。

Process Explorerで報告されているように、これはWindows 10上にあります。

私が答えたいと思う究極の質問は、次のとおりです。スペース不足のSSDは、物理メモリを実際に効果的に使用できるようにするために、自分のページファイルを人工的に膨らませるのを避けることができますか。 (あるいは、それがいっぱいでなかったとしても。「あなたのページファイルにX / Y / Zをする」といった提案は避けたいのです。)


コミット料金は、RAM使用量、ページファイル使用量、またはその2つの組み合わせとは関係ありません。これは基本的にRAMまたはページファイルのいずれかに存在する可能性のある、必要とされる潜在的なストレージスペースの合計です。コミット制限は、RAMサイズ+ページファイルサイズ - わずかなオーバーヘッドです。したがって、コミット制限を増やす唯一の方法は、ページファイルサイズを増やすか、RAMを追加することです。通常前者が最も簡単です。
LMiller7

あなたはすでに同じくらい言いましたが、さらに詳しく述べる時間がないと言いました。これが私がここで尋ねることにした理由です。私が理解しているように、コミットチャージは「何か、ある時点でこれだけのメモリを要求し、OSが完了した」と言っており、コミットチャージはメモリの使用の有無にかかわらずこれを反映しています。しかし、それは私が持っている質問のほとんどには答えません。少なくとも最後の質問に対する答えがほしいのですが、理想的には、Windowsでのメモリ管理のしくみについて、より深く、より明確な図を得たいと思います。
martixy

回答:


7

コミット担当が代表的なものにすぎないことを理解すれば、これは実際にはかなり簡単です。 潜在的な それでも「プライベートワーキングセット」(これは「コミットされた」メモリによって使用されるRAMです) - 仮想メモリの使用 実際の ページファイルスペースと同じように使用します。 (しかし、これはRAMの使用のすべてではありません、RAMを使用する他のものがあるので)。

32ビットシステムについて話しているとしましょう。そのため、各プロセスで利用可能な最大仮想アドレス空間は通常2 GiBです。 (実質的な違いはありません。 どれか 64ビットシステムでは、アドレスとサイズが大きくなる可能性があることを除けば、次のようになります。

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

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

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

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

それであなたはそれを持っています!コミット料金は増加しましたが、物理メモリー使用量は増加しませんでした。

これはsysinternalsツールで簡単に実証できます testlimit

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

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

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

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

  1. OSはプロセスワーキングセットからページを削除します。
  2. ワーキングセットに入れられてから書き込まれたため、変更されたページリストに追加されます(そうでない場合はスタンバイページリストに追加されます)。ページテーブルエントリはまだRAMのページの物理ページ番号を反映していますが、今ではその「有効」ビットがクリアされているので、次にそれが参照されるときにページフォルトが発生します
  3. 変更されたページリストが小さなしきい値に達すると、 修正ページライター 「システム」プロセスのスレッドが起動し、変更されたページの内容をページファイルに保存します(ページがあると仮定します)。
  4. それらのページを変更されたリストから取り除き、それらを待機リストに入れます。それらは現在「利用可能な」RAMの一部と見なされています。しかし今のところ、彼らはまだ彼らがそれぞれのプロセスにいた時からのオリジナルのコンテンツを持っています。繰り返しますが、コミット料金は変わりませんが、RAM使用量とプロセスのプライベートワーキングセットは減少します。
  5. 待機リストのページは 転用 これは、システム上の任意のプロセスからのページフォルトの解決、またはSuperFetchによる使用など、他の目的で使用されることを意味します。しかしながら...
  6. 物理ページが再利用される前に、変更リストまたは待機リストにあるページを失ったプロセスがそのページに再度アクセスしようとすると、ディスクから読み取ることなくページフォルトが解決されます。ページは単にプロセスワーキングセットに戻され、ページテーブルエントリは「有効」になります。これは、「ソフト」または「安い」ページフォルトの例です。待機リストと変更リストは、近いうちに再び必要になる可能性があるページのシステム全体のキャッシュを形成すると私たちは言います。

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

  1. 内容を書く場所がないので、ページは修正されたリストの上にあります。

  2. 内容を書く場所がないので、ページは修正されたリストの上にあります。

  3. 内容を書く場所がないので、ページは修正されたリストの上にあります。

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

専用のコミット済みメモリ以外にも、仮想アドレス空間およびRAMを使用する方法があります。がある マッピングされた バッキングストアがページファイルではなく指定されたファイルである仮想アドレス空間。マップされたv.a.sのページ。ページインされたものはRAMの使用量に反映されますが、マップファイルはバッキングストアを提供するため、マップメモリ​​はコミットには寄与しません。もう1つの違いは、ほとんどのファイルマッピングをプロセス間で共有できることです。あるプロセスのためにすでにメモリ内にある共有ページは、再びディスクにアクセスすることなく別のプロセスに追加できます(別のソフトページ障害)。

そこには ページング不可 これは常にRAMに常駐しているため、バッキングストアはありません。これは、報告されたRAM使用量と「コミット料金」の両方にも貢献します。

これは圧縮によるものと思われます。これは質問を変容させる:なぜコミット制限が上がらないのか、それとも何かなのか?すなわちメモリ使用量が少ない場合、圧縮のポイントは何ですか?

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

コミット料金がいっぱいになり、Windowsが物事を閉じるように私に頼み始めたとき、ほとんどの場合物理メモリは約60%です。これは非常に非効率的です。

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

「コミットチャージ」と「コミットリミット」メカニズム全体の理由は、次のとおりです。VirtualAllocを呼び出すときに、戻り値をチェックして、ゼロでないかどうかを確認します。それがゼロの場合、それは私の割り当ての試みが失敗したことを意味します。あまりコミットしないようにするか、プログラムを正常に終了させるなど、合理的なことを行うべきです。

VirtualAllocがゼロ以外、つまりアドレスを返した場合、それはシステムが保証を行ったことを意味します。 になります アクセスすることを選択した場合に利用可能です。それをすべて置く場所があること - RAMかページファイルのどちらか。すなわち、その地域内の何かにアクセスすることにおいて何らかの種類の失敗を予期する理由はありません。それは良いことです、なぜなら私が「それはうまくいったのか」をチェックすることを期待するのは合理的ではないからです。割り当てられた領域へのアクセスごとに。

「現金貸し出し銀行」アナロジー

それは銀行がクレジットを提供するのと少し似ていますが、厳密には手元現金に基づいています。 (これはもちろん、実際の銀行がどのように機能するかではありません。)

銀行が手元に100万ドルの現金で始まるとします。人々は銀行に行き、さまざまな金額で与信枠を求めます。銀行が私に10万ドルの与信枠を承認したとします(私は個人的な献身的な地域を作ります)。それは現金が金庫から実際に出ていったという意味ではありません。私が後で実際にたとえば2万ドル(私はこの地域の一部にアクセスする)のローンを借りると、それは銀行から現金を取り除くことになります。

しかし、私が融資をするかどうかにかかわらず、私が最高10万ドルを承認されたという事実は、その後その銀行がすべての顧客に対して合計90万ドル相当の信用枠しか承認できないことを意味します。銀行は現金準備を超えるクレジットを承認しません(つまり、承認しません)。 オーバーコミット というのは、銀行は、後で承認しようとする意思が現れたときに、以前に承認された借り手を引き離さなければならない可能性があるためです。 彼らの ローン。銀行はすでに 献身的 それらのローンを許可することに、そして銀行の評判は急降下するでしょう。

はい、これは銀行によるその現金の使用という点では「非効率的」です。そして、顧客が承認されている与信枠と実際に融資する金額との間の格差が大きいほど、効率が悪くなります。しかし、その非効率性は銀行のせいではありません。それは、そのような高い与信枠を要求するための顧客の「せい」ですが、小額の融資をするだけです。

銀行のビジネスモデルは、以前に承認された借り手が自分のローンを借りるために現れたときに、それを単純に拒否することができないということです。だからこそ、銀行はローンファンドのどれだけが「コミット」されたかを注意深く追跡しています。

私は、ページファイルを拡張すること、あるいは別のものを追加することは、銀行が出ていってより多くの現金を得てそれをローンファンドに追加することに似ていると思います。

この類推でマップされたページング不可能なメモリをモデル化したいのであれば...ページング不可能はあなたがあなたがあなたの口座を開くときに出し入れしておくことを要求される小さなローンのようなものです。マップされたメモリは、自分の現金を(マップされているファイル)まとめて銀行に預け入れ、次にその一部のみを取り出して(ページインする)ようなものです。一度にすべてのページを表示しないのはなぜですか。私は知りません、多分あなたはあなたの財布の中にそのような現金をすべて入れる余地がないでしょう。あなたが預けた現金は一般のローン資金ではなくあなた自身の口座にあるので、これは他人のお金を借りる能力に影響を与えません。この類推は、特に共有メモリについて考え始めたときに、そこについては崩れ始めています。

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

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

すみません、申し訳ありませんが、コミット限度に達している場合は、できることは3つだけです。

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

オプション2に関して:あなたはハードドライブに2番目のページファイルを置くことができます。あまりにも多くの空きRAMがあるために、アプリケーションが実際にすべてのコミットメモリを使用していない場合(実際には使用されていないようです)、実際にはそのページファイルにあまりアクセスしないのでパフォーマンスを傷つけます。それでもハードドライブの速度が遅くなっても気になる場合は、小型で安価なセカンドSSDを用意し、それにセカンドページファイルを追加するという方法もあります。 1台の「ショーストッパー」は、2台目の「取り外し不可能」ドライブを追加する方法がないラップトップです。 (Windowsは、USBで接続されたもののように、取り外し可能なドライブにページファイルを置くことを許可しません。)

ここは 私が書いたもう一つの答え それは別の方向から物事を説明します。

p.s .:あなたはWindows 10について尋ねたが、私はそれがNTファミリーのすべてのバージョンで同じように動作することをあなたに言うべきである。変更された可能性があるのは、Windowsのページファイルサイズのデフォルト設定で、1.5倍または1倍のRAMサイズからはるかに小さいサイズまでです。これは間違いだったと思います。


1
+1これは私が書いたべき答えです。これがまさに現代のOSのしくみです。 SSDの前には問題にはなりませんでした。RAMがそれほど多くなく、ハードドライブのスペースがたくさんあったからです。多くのRAMがあり、一部のマシンにはそれほど多くの大容量記憶領域がないため、十分なページングファイル領域を確保することが再び問題になっています。あなたのマシンがRAMを効率的に利用できるように、それを優先にしてください。
David Schwartz

@ DavidSchwartz:MM問題に関するあなたの答えの多くを見ました、そして私はあなたから来ることを言わなければなりません、それは高い評価です。ありがとうございました。
Jamie Hanrahan

光が消えています。それがすべて(まあ、ほとんど)最後に理にかなっています。これとあなたの他の答えを読んでください、それぞれ新しい洞察を提供しました。私はその本を試して調べようとさえしたくない。特に、私は最初にこの質問を(質問の下での意見交換によって示唆されるように)内部フォーラム以外では行わなかったが、それは少し死んでいるように思われる。ダビデが言ったこともまた真実です。この質問は、ある意味では少し遅れています。最近新しいSSDを入手して追加のページファイルを用意することができるからですが、以前の超小型ドライブでは本当に問題でした。 ...以下に続く...
martixy

...上から続けた。ちなみに、私自身の調査で、Linuxや多くのVMハイパーバイザーには「オーバーコミット」と呼ばれるオプションがあるため、これが唯一の方法ではないことがわかりました。実際、Windowsがメモリ割り当てのアプローチになると、少数派になるようです。ああ、そしてそれについて考えるとき、私は多かれ少なかれ同じ銀行の類推を思いついた。偶然の一致はすごいです。
martixy

しかし、これらの「オーバーコミット」オプションは常にこの特定の概念を参照するわけではありません。汎用OSの仮想メモリは、OSから「割り当てに成功しました」と言われると、物理メモリと同じようにプログラマに動作するようになっています。 。のオーバーコミットを許可することに関する問題 すべて 仮想を実現することができる物理的記憶装置のうちの1つは、単純なメモリがi = * jのように参照することである。上げるかもしれない 致命的 たとえiがあなたのスタック上にあり、jが以前におそらく有効なポインタとして返されたとしても、エラー。 (続き...)
Jamie Hanrahan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.