execve() のマニュアルページは次のように言います。
execve() はファイル名を指すプログラムを実行します。これにより、呼び出しプロセスで現在実行されているプログラムが新しいプログラムに置き換えられます。新しく初期化されましたスタック、ヒープ、およびデータセグメント(初期化および初期化されていません)
呼び出しプロセスがvfork()によって生成された場合exec() は新しいプログラムに新しいアドレス空間を提供することを意味し、親アドレス空間を変更しません。。
呼び出しプロセスがより一般的にfork()によって生成される場合、以前の「スタック、ヒープ、およびデータセグメント(初期化および初期化されていません)」は一般的にどうなりますか?彼らのスペースが確保されましたか?
execve() の動作は、呼び出しプロセスの生成方法によって異なりますか?
参照を見る前に、私はexecve()が新しいエントリを作成するのではなく、以前の「スタック、ヒープ、およびデータセグメント(初期化および初期化されていません)」を上書きすると思いました。それで、この文章を見て、なぜ新しい空間を無駄にするのか気になりました。
ありがとうございます。
答え1
execve() の動作は、呼び出しプロセスの生成方法によって異なりますか?
いいえ。
参照を見る前に、私はexecve()が新しいエントリを作成するのではなく、以前の「スタック、ヒープ、およびデータセグメント(初期化および初期化されていません)」を上書きすると思いました。
いいえ:execve()は新しいセグメントを作成し、古いセグメントを解放します。
それで、この文章を見て、なぜ新しい空間を無駄にするのか気になりました。
覚えておいて、私たちは仮想メモリについて話しています!
空のセグメントを作成すると、セグメントを追跡するために少量の物理メモリしか割り当てられません。この割り当てサイズは、セグメントサイズに関係なく固定されます。
作成した各ページに物理ページを割り当てる必要があります。親プロセスが多数のページを作成した可能性があります。ただし、子プロセスが実行中にわずかなスタック/ヒープ/データのみを使用する場合、親プロセスのすべてのダーティページへの参照を維持する理由はありません。親プロセスが終了し、子プロセスが実行され続けると、メモリが無駄になります。
古いセグメントやページへの参照を削除するのが最も効果的な方法です。もしそうならただこのメモリを参照することで、物理メモリを解放できます。