メモリマップされたセグメントとヒープが出会うまで増加し続けますか?

メモリマップされたセグメントとヒープが出会うまで増加し続けますか?

私は2つのソース、つまりプロセスのメモリレイアウトのメモリマッピングセグメントから共有メモリセグメントの範囲を見つけようとしました。


~からhttps://manybutfinite.com/post/anatomy-of-a-program-in-memory/、プロセスのメモリレイアウト図が見つかりました。

メモリマップされたセグメントとヒープが出会うまで増加し続けますか?

それとも、スタックセグメントのRLIMIT_STACKと同様に、2つのセグメントの成長に制限がありますか?

ここに画像の説明を入力してください。


Linuxプログラミングインターフェースから

ヒープとスタックを増やすためのスペースを許可するために、共有メモリセグメントは仮想アドレス0x40000000から始まり接続されます。マッピングマッピング(49章)と共有ライブラリ(41章と42章)もこの領域に配置されます。 (カーネルのバージョンとプロセスの RLIMIT_STACK リソース制限の設定によっては、共有メモリマップとメモリセグメントのデフォルトの配置に若干の違いがあります。) アドレス 0x40000000 は、カーネル定数 TASK_UNMAPPED_BASE として定義されます。

共有メモリセグメントはTASK_UNMAPPED_BASEから始まり、上向きに増加しますか?

上の図は、共有メモリセグメントが下向きに増加することを示しているので、上向きに成長するのか、それとも下向きに成長するのですか?

ここに画像の説明を入力してください。

ありがとうございます。

ベストアンサー1

mmapセグメントとヒープセグメントにはいくつかの制限が適用されます。RLIMIT_AS使用可能な総アドレス空間を決定します。これには、プログラムが作成できるすべてのメモリ割り当てが含まれます。RLIMIT_DATAデータセグメントの最大サイズを決定します。

カーネルはこれらの制限についてスタック拡張とmmapヒープbrk割り当てをチェックします。また、競合の可能性があるセグメントへの割り当てを確認するため、セグメントが互いに上書きされないようになります(たとえば、参照)。ヒープ割り当てに対して実行される検査brk)。割り当てができない場合は、プログラムに適切に「通知されます」。 Cライブラリはエラーを返し、ENOMEMスタックを拡張できない場合、brkカーネルは次のようにプログラムを終了します。SIGSEGV

共有メモリセグメント(厳密に言えば、カーネルの観点から仮想メモリ領域)が大きくなる方法は、メモリレイアウトによって異なります。これはプロセスごとに大きく異なる可能性があります。ほとんどのアーキテクチャでは、「伝統的な」メモリマッピングがありますTASK_UNMAPPED_BASE。非伝統的なメモリマッピングはトップダウン割り当てをもたらす。バラよりarch_pick_mmap_layout()そしてmmap_is_legacy()x86アーキテクチャを例にしてみましょう。setarch'フラグを使用して古いメモリマップに切り替えることができます-L(下記の例を参照)。

実際に/proc/$$/mapsロードされた共有ライブラリのアドレス(存在する場合)とロードされた順序を表示して調べて、セグメントがどのように増加するかを理解できます。動的リンカーは常に最初にロードされます。そのアドレスが他のライブラリよりも低い場合、割り当てはボトムアップ、それ以外の場合はトップダウンです。 64ビットx86システムの出力を比較しますcat /proc/self/mapssetarch x86_64 -L cat /proc/self/maps

おすすめ記事