ヒープは、スタックと同様に、プロセスごとであり、(ほぼ)純粋にユーザースペースのものです。
ヒープマネージャは、sbrk
syscallを使用して、必要なメモリ量を増やす予定であることをオペレーティングシステムに通知します。これは、ページの範囲を「不明」から「存在する、ゼロ、アクセスされない」に変更することとほとんど変わりません(これは、実際にはまだ存在しないことを意味しますが、OSは存在するふりをします)。ページが最初にアクセスされると、障害が発生し、OSはゼロプールからゼロページをプルします。
(大量のメモリが上から解放された場合、ヒープマネージャもデータセグメントを縮小する可能性があるため、少し複雑になる可能性がありますが、基本的にはそれと同じくらい簡単です)。
OSがヒープについて知っているのはこれだけです。ブロックの分割、解放されたブロックのリストまたは同様の構造への配置、ブロックの再利用など、その他すべては、プログラムの直接的または間接的(たとえば、glibcの一部として)部分であるヒープマネージャー内で行われます。
ヒープマネージャーが実行しているのは実装に依存することです。さまざまな方法で機能する、よく知られているさまざまなmalloc実装が少なくとも半ダース存在します。たとえば、これまたはこれまたはこれを参照してください。
スタックは同じまたは同様の方法で機能します。特定のメモリ範囲は、実際には何も予約せずに(つまり、ページを作成せずに)最初に「予約」されます。いくつかのページがコミットされ(つまり、作成され)、最後のページは書き込み保護されているか存在しないかのいずれかであり、これは特別な方法で記憶されます。スタックが大きくなり、この最後のページに触れると、障害が発生します。次に、スタックがまだ許容サイズ内にある場合、新しいページがゼロプールからプルされます。
プロセスが終了すると、それらのページへのすべての参照が削除され、(参照を保持している別のプロセスと共有されていない場合)優先度の低いバックグラウンドタスクに渡され、ゼロにされて「ゼロプール」に追加されます。