Linux システムでさまざまなメモリの問題に遭遇したことがありますか?メモリリーク、メモリの断片化など。これらの問題は、Linux カーネルのメモリ断片化防止テクノロジを深く理解することで解決できます。
Linux カーネルが物理メモリを編成および管理する方法はバディ システムであり、物理メモリの断片化はバディ システムの弱点の 1 つです。断片化の問題を防止および解決するために、カーネルはいくつかの実用的なテクノロジを採用しています。ここではこれらのテクノロジーについて説明します。要約を作成します。
バディからメモリ ページを適用します。適切なページが見つからない場合は、圧縮と再利用という 2 つのステップのメモリ調整が実行されます。前者はフラグメントを統合してより大きな連続メモリを取得するものであり、後者は必ずしもメモリを占有しないバッファ メモリをリサイクルするものです。ここでの焦点は、comact を理解することです。全体のプロセスは大まかに次のとおりです。 リーリー
GFP_FS および __GFP_IO; さらに、ゾーンの残りのメモリは特定の条件を満たす必要があります。カーネルはそれを「断片化インデックス」と呼びます。この値は 0 ~ 1000 です。デフォルトの断片化インデックスは、次の場合にのみ使用できます。は 500 より大きいです。compact の場合、このデフォルト値は proc ファイル exfrag_threshold を通じて調整できます。断片化インデックスは、fragmentation_index 関数を通じて計算されます:リーリー
メモリ断片を統合するプロセス中、断片化されたページはこのゾーン内でのみ移動され、ゾーン内の低いアドレスにあるページは可能な限りゾーンの最後に移動されます。新しいページの場所の適用は、compaction_alloc 関数を通じて実装されます。移動プロセスは同期と非同期に分かれており、メモリ アプリケーションが失敗した後、最初の圧縮では非同期が使用され、その後の再利用では同期が使用されます。同期プロセスは現在使用されていないページのみを移動し、非同期プロセスは移動する前にすべての MOVABLE ページを移動して使用されるのを待ちます。
再利用可能: 移動はできませんが、削除してリサイクルできます。たとえば、ファイル マップド メモリ;
MOVABLE: 自由に移動可能で、ユーザー空間メモリは基本的にこのタイプに属します。
メモリを申請する場合、モビリティに応じて、まず指定された種類の空きページにメモリを申請します。各ゾーンの空きメモリは次のように構成されます。
リーリー
指定されたタイプの free_area でメモリを要求できない場合、バックアップ タイプからメモリを転送できます。転送されたメモリは、新たに指定されたタイプ リストに解放されます。カーネルはこのプロセスを「盗難」と呼びます。
代替タイプの優先順位リストは次のように定義されます:
すべてのシナリオがモビリティによるページの編成に適しているわけではないことに注意してください。メモリ サイズがさまざまなタイプに割り当てるのに十分でない場合、モビリティを有効にするのは適していません。有効かどうかを示すグローバル変数があり、メモリの初期化中に設定されます:
リーリー
各メモリ領域が持つ少なくともページ数を決定するパラメータ、pageblock_nr_pages があり、次のように定義されます。
#pageblock_order HUGETLB_PAGE_ORDER を定義します
リーリー
システムの初期化中に、すべてのページが MOVABLE としてマークされます:
他のモビリティ タイプのページは後で生成されますが、これが上記の「盗用」です。これが発生すると、小さなフラグメントの生成を避けるために、フォールバック内の優先度の高い、より大きな連続ページが通常「盗まれ」ます。
リーリー/proc/pageteypeinfo を通じて、現在のシステムのさまざまなタイプのページ分布を表示できます。
3
1. enum zone_type { 2. \#ifdef CONFIG_ZONE_DMA 3. ZONE_DMA, 4. \#endif 5. \#ifdef CONFIG_ZONE_DMA32 6. ZONE_DMA32, 7. \#endif 8. ZONE_NORMAL, 9. \#ifdef CONFIG_HIGHMEM 10. ZONE_HIGHMEM, 11. \#endif 12. ZONE_MOVABLE, 13. __MAX_NR_ZONES 14. };
ZONE_MOVABLE的启用需要指定kernel参数kernelcore或者movablecore,kernelcore用来指定不可移动的内存数量,movablecore指定可移动的内存大小,如果两个都指定,取不可移动内存数量较大的一个。如果都不指定,则不启动。
与其它内存域不同的是ZONE_MOVABLE不关联任何物理内存范围,该域的内存取自高端内存域或者普通内存域。
find_zone_movable_pfns_for_nodes用来计算每个node中ZONE_MOVABLE的内存数量,采用的内存区域通常是每个node的最高内存域,在函数find_usable_zone_for_movable中体现。
在对每个node分配ZONE_MOVABLE内存时,kernelcore会被平均分配到各个Node:
kernelcore_node = required_kernelcore / usable_nodes;
在kernel alloc page时,如果gfp_flag同时指定了__GFP_HIGHMEM和__GFP_MOVABLE,则会从ZONE_MOVABLE内存域申请内存。
总之,Linux kernel内存碎片防治技术是一个非常重要的概念,可以帮助你更好地理解Linux系统中的内存管理。如果你想了解更多关于这个概念的信息,可以查看本文提供的参考资料。
以上がLinux カーネルのメモリ断片化防止テクノロジ: メモリ管理の深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。