質問: linuxはどのようにして物理メモリの断片化をリアルタイムで削減しますか? linuxメモリアロケータは、ページを物理メモリから仮想メモリにマッピングすることで機能します。連続領域またはスパースチャンクを物理メモリから仮想メモリの連続領域にマップできます。バディアルゴリズムを使用すると、物理メモリを連続したページのセットに配置できます(バケットと呼びましょう)。 1つのバケットに含まれるページ数は常に2の累乗です。これにより、小さなバケットを1つの大きなバケットに簡単にグループ化できます(たとえば、1ページがオーダー0バケットを構成し、2オーダー0バケットがオーダーを構成します- 1バケット、2注文-1バケットは注文2バケットを構成します。)時間の経過とともに、物理メモリが断片化され、特定のサイズのバケットを割り当てることができなくなります。そのため、カーネルは、物理メモリ全体に分散している小さなバケットを割り当てることを余儀なくされます。問題は、linuxカーネルは、より大きなバケットが使用可能になる可能性を高めるために、これらのバケットをリアルタイムで再配置するのでしょうか。もしそうなら、それはどのようにこれを達成しますか?
回答: ここでは、linuxカーネルで使用されるメモリ割り当てについて説明しています。プロセスram割り当てではなく、ページごとです。このアルゴリズムは、ページのサイズまでの少量のメモリを処理します。最新のカーネルでのみ、リクエストを1ページより大きくすることが可能になりました。私の知る限り、カーネルはメモリを再配置しません。つまり、ガベージコレクションはありません。割り当てられたオブジェクトの一部は、重要なプロセスで使用されると移動できない可能性があるためです。メモリが断片化されすぎて要求された量を割り当てることができない場合、カーネルは次のいずれかを実行できます。 使用可能なメモリがない状態で要求を失敗させます。 バディシステムによって断片化が処理されることを期待して、後で実行するように要求をスケジュールします。これは、カーネルのクリティカルでないセクションでのみ可能です。 重要なサブシステムには、そのパーセルを管理するために、最初からメモリのチャンクが割り当てられる場合があります。 一部のカーネルメモリはスワップ可能であり、優先度の高いルーチンから要求された場合に書き出されます。 カーネルソフトウェアを作成する際の基本的なルールは、完了するために必要なリソースを保証せずに実行を確約しないことです。適切に記述されたカーネルルーチンは、開始する前に、メモリを含むすべてのリソースを最初に割り当てます。これにより、バックトラックと古い状態を保存する必要がなくなります。これは、ルーチンがすでに何らかの作業を行った後にエラーが発生した場合に必要になるため、失敗状態を返す前に、行ったすべてを元に戻す必要があります。詳細については、linux journalの記事 memory allocation を参照してください。