最新のオペレーティング システムでは、ハードウェア RAM に直接アクセスすることはできず、代わりにいわゆる仮想メモリに抽象化され、オンデマンドで RAM にマップされます。通常、各プロセスには、完全なアドレス空間の独自のプライベート コピーが与えられます。これにより、OS は実行時にプロセスのメモリを RAM 内で移動したり、ディスクにスワップアウトしたりすることができます。これは透過的に行われます。つまり、プロセスはそのような再配置について通知されず、これを処理するためのコードは必要ありません。(一部のリアルタイム アプリケーションでは、メモリがスワップ アウトされるのを防ぐための手法が使用される場合があります)。
オブジェクト ファイルを実行可能ファイルまたは動的ライブラリにリンクする場合、リンカは関数/メソッドの cpu 命令とすべてのグローバル変数にメモリを静的に割り当てます。OS が実行可能ライブラリまたは動的ライブラリをロードすると、この事前に割り当てられたメモリが実際のメモリにマップされます。
起動時に、各スレッドはスタックと呼ばれるプライベート メモリ領域を受け取ります。関数/メソッドを呼び出すたびに、コンパイラは、関数/メソッドが使用するすべてのパラメーター、ローカル変数、および戻り値 (存在する場合) を保持するのに十分なメモリを (スタック ポインターをインクリメントすることによって) スタックから自動的に割り当てるコードを挿入します。コンパイラは、一部の変数をプロセッサ レジスタに残すだけで十分であると判断した場合、スタックにメモリを割り当てません。関数/メソッドが戻ると、コンパイラによって生成されたコードが実行され、(スタック ポインターをデクリメントすることによって) このメモリが解放されます。スタック上のオブジェクトのデストラクタは、それらが定義されているブロックが終了するときに呼び出されることに注意してください。これは、戻るまでに長い時間がかかる可能性があります。また、コンパイラは、割り当てられたメモリを自由に再利用できます。
例外がスローされると、コンパイラ コンパイラは、スタックのレイアウトを認識し、適切な例外ハンドラが見つかるまでそれをアンワインドできる特別なコードを挿入します。
これとは対照的に、ヒープ上のメモリはnew
/を使用して割り当てられdelete
、コンパイラはシステム ライブラリを使用してメモリを要求または解放するコードを挿入します。
これは、メモリ割り当てがどのように機能するかを理解するための簡単な説明であることに注意してください。