0

動的メモリ割り当ての低レベルのものについて質問があります。さまざまな実装がある可能性があることは理解していますが、基本的な考え方を理解する必要があります。

そう、

最新の OS メモリ アロケータまたは同等のものがメモリ ブロックを割り当てる場合、このブロックを解放する必要があります。

しかし、それが起こる前に、割り当てプロセスを制御するシステムが存在する必要があります。

私は知る必要がある:

  • このシステムが割り当てられたメモリと割り当てられていないメモリを追跡する方法。つまり、システムは、割り当てと割り当て解除のプロセスでこの情報を使用するために、既に割り当てられているブロックとそのサイズを知る必要があります。

このプロセスは、割り当てビットなどの最新のハードウェアでサポートされていますか? または、割り当て情報を格納するために使用されるある種のデータ構造です。データ構造がある場合、割り当てられたメモリと比較してどのくらいのメモリを使用していますか?

小さなチャンクではなく大きなチャンクでメモリを割り当てる方が良いですか?その理由は?

基本的な実装の詳細を明らかにするのに役立つ回答を歓迎します。

コード例が必要な場合は、C または C++ で問題ありません。

4

3 に答える 3

1

通常、2 つの異なるレイヤーが存在します。

1 つのレイヤーは、通常は C 標準ライブラリの一部として、アプリケーション レベルに存在します。これは、mallocandのような関数を介して呼び出すものですfree(またはoperator newC++ では、通常は を呼び出しますmalloc)。このレイヤーは割り当てを処理しますが、メモリやそれがどこから来るかは知りません。

OS レベルのもう一方のレイヤーは、ユーザーの割り当てを認識せず、気にしません。予約、割り当て、アクセスされた固定サイズのメモリ ページのリストと、マップ先などの各ページ情報のみを保持します。

どちらの層にも多くの異なる実装がありますが、一般的には次のように機能します:
メモリを割り当てるとき、アロケータ (「アプリケーション レベルの部分」) は、それが提供できる本のどこかに一致するブロックがあるかどうかを調べます (一部のアロケータは、必要に応じて大きなブロックを 2 つに分割します)。

適切なブロックが見つからない場合は、オペレーティング システムから新しいブロック (通常は要求したものよりもはるかに大きい) を予約します。sbrkまたはmmapLinux、またはVirtualAllocWindows では、その効果のために使用される関数の典型的な例になります。これは、オペレーティング システムに意図を示し、いくつかのページ テーブル エントリを生成する
以外には、ほとんど何もしません。
次に、アロケータは (理論上は論理的に) 通常の動作モードに従ってその大きな領域を小さな断片に分割し、適切なブロックを見つけて、それをユーザーに返します。この返されたメモリは必ずしも物理メモリとして存在するとは限らないことに注意してください (ただし、ほとんどのアロケータは、割り当てられた各ユニットの最初の数バイトにメタデータを書き込むため、必ずページを事前フォールトします)。

その間、バックグラウンド タスクは、あるプロセスで一度使用されたが解放されたメモリ ページを目に見えないようにゼロにします。遅かれ早かれ誰かがメモリを要求するため、これは一時的なベースで常に発生します (多くの場合、それはアイドル タスクが行うことです)。

割り当てられたブロックを含むページのアドレスに初めてアクセスすると、エラーが発生します。このまだ存在しないページ (物理的にではなく、論理的に存在する) のページ テーブル エントリは、ゼロ ページのプールからのページへの参照に置き換えられます。何も残っていないというまれなケースでは、たとえば、大量のメモリが常に割り当てられている場合、OS は、すぐにはアクセスされないと思われるページをスワップアウトし、ゼロにして、このページを返します。
これで、ページはワーキング セットの一部になり、実際の物理メモリに対応し、プロセスのクォータに加算されます。プロセスの実行中に、必要なメモリの量とアクセス方法に応じて、特定の制限を超えると、ページがワーキング セットに出入りしたり、ページ アウトされたりインされたりすることがあります。

を呼び出すfreeと、アロケータは解放された領域をブックに戻します。代わりに、メモリがもう必要ないことを OS に通知する場合がありますが、実際には必要ないため、通常は発生しません。少し余分なメモリを保持して再利用する方が効率的です。また、通常、割り当て/割り当て解除するユニットは、OS が動作するユニットと直接対応していないため、メモリを解放するのは簡単ではない場合があります (また、sbrk正しい順序で発生する必要がある場合) )。

プロセスが終了すると、OS は単にすべてのページ テーブル エントリを破棄し、アイドル タスクがゼロにするページのリストにすべてのページを追加します。したがって、物理メモリは、次のプロセスが要求するために利用できるようになります。

于 2013-06-03T20:24:51.677 に答える