1

私は、ランタイムアドレスバインディングでは、プログラムに物理メモリ内のフレームを不連続に割り当てることができることを知りました。また、hereおよびhereのように、論理アドレス空間内のプログラムのすべてのセグメントは連続していますが、すべてのセグメントが並べて配置されているわけではありません。テキスト、データ、BSSおよびヒープ・セグメントは一緒に配置されますが、スタック・セグメントは配置されません。言い換えると、物理アドレス空間のどのフレームにもマッピングされていない論理アドレス空間内のヒープとスタックセグメント(プログラムブレークとスタックトップの間)の間のページが存在するため、論理アドレス空間が非 - 実行時アドレスバインディングの場合は連続しています。コンパイル時またはロード時バインディングの場合のメモリレイアウトについてプログラムのメモリレイアウトはアドレスバインディング手法に依存しますか?

enter image description here

しかし、何?論理アドレス空間は抽象的なアドレス空間ではなく実際の物理アドレス空間であり、プログラムはどのように物理メモリに配置されているのでしょうか?具体的には、スタックセグメントはプログラムの物理アドレス空間にどのように配置されますか?残りのセグメントと一緒に配置されるのか、実行時バインドの場合と同じように別々に配置されますか?

答えて

0

質問に答えるには、まず、最新のオペレーティングシステムで、stackheapの割り当てについて少し説明しなければなりません。

stackは、メモリの割り当てを継続することです。ここで、cpuはpushpopコマンドを使用してスタックの先頭からデータを追加/削除します。私はあなたがすでにスタックの仕組みを知っていると仮定します。プロセスストア - 戻りアドレス関数の引数およびローカル変数をスタックオーバーします。関数が呼び出されるたびに、より多くのデータがプッシュされます(最終的にはスタックオーバーフローにつながる可能性があります。データがポップされることはありません - 無限再帰)。スタックサイズは、プログラムがメモリにロードされるときに固定されます。ほとんどのプログラミング言語では、コンパイル時にスタックサイズを決めることができます。そうでない場合、デフォルトを決定します。 Linuxでは、最大スタックサイズ(ハードリミット)はulimitで制限されています。サイズはulimit -sで確認、設定できます。

しかし、ヒープスペースは、* nixシステムに上限がありません(ulimit -vを使って確認してください)、すべてのプログラムはデフォルト/設定量のヒープで始まり、必要に応じて増やすことができます。プロセスのヒープスペースは、実際には2つのリンクされたリストfreeusedブロックです。ヒープからのメモリ割り当てが必要なときはいつでも、1つ以上の空きブロックが結合されて大きなブロックを形成し、使用済みリストに単一のブロックとして割り当てられます。解放するとは、ブロックを使用済みリストから空きリストに削除することです。ブロックを解放した後、ヒープは外部断片化を持つことができます。今度は空きブロックの数がデータ全体を含むことができない場合、プロセスはOSからより多くのメモリを要求します。一般に、新しいブロックは上位アドレスから割り当てられます。そこで、ヒープ成長の上向きの図を示します。私は言い換えます - ヒープは高い方向に連続的にメモリを割り当てません

質問にお答えします。

コンパイル時またはロード時のアドレスバインディングでは、スタックと ヒープセグメントはプログラムの物理アドレス空間にどのように配置されますか?

固定スタックは、コンパイル時に割り当てられ、ヒープメモリが割り当てられます。どのように配置されているかは上で説明した。

ヒープとスタックの間のスペースは、プログラム のために予約されていますか、またはOSが他のプログラムに使用できるのですか?

はいこれはプログラム用に予約されています。しかし、プロセスはヒープに空きブロックを追加するために、より多くのメモリを要求できます。それはそれ自身のヒープを共有することとは異なります。

注:質問が広いので、ここで説明できるトピックがたくさんあります。それらの中には、ガベージコレクション、ブロック選択、共有メモリなどがあります。私はすぐにここに参照を追加します。

参考資料: -

関連する問題