メモリのスタック領域とヒープ領域の違いについてまとめてみました!
スタック領域
関数が呼び出されるときに割り当てられる領域。関数のパラメータ、ローカル変数、戻り値がスタックにプッシュされ、終了するとポップされ取り出される。後入れ先出し(LIFO)により管理されるのが特徴で、関数呼び出しのネスト構造と相性が良い。
割当タイミング
プログラムが起動するときにOSによって自動的に割り当てられる。サイズはコンパイル時に固定された値となる。
サイズ
主に関数の呼び出しとローカル変数の格納に使用されるため比較的小さいサイズとなる。
メモリ解放
関数が終了すると自動的に開放される。
断片化のリスク
スタックは後入れ先出し(LIFO)により管理されるため、メモリの確保と開放が常にスタックのトップで行われており断片化が起こりにくい。
エラー:スタックオーバーフロー
深いor無限の再起関数呼び出しや、極端に多くの変数を割り当てた場合などに発生する。
ヒープ領域
プログラム全体を通じて存在する必要があるデータを管理するための領域。Javaで言うところのnewしたデータはヒープ領域を使用する。
割当タイミング
ヒープ領域は動的に割り当てられるメモリ領域であるため、プログラムの実行時にサイズが決定される。
サイズ
大きなデータや長期間存在するデータを格納するため、スタックと比較して大きなサイズとなる。
メモリ解放
本来は自動で開放される領域ではないため、プログラマが明示的にメモリ解放することが必要となる。しかし、現代で使用されるJava・Python・Go・JavaScriptなどの主要プログラミング言語にはGCが備わっており、明示的にメモリ解放しなくても不要になったメモリを自動的に開放している。
※適切に参照を制御してGCの対象とすることが必要。
断片化のリスク
ヒープは任意の位置でメモリ確保と開放が行われるため断片化が起こりやすい。
外部断片化
メモリの空き領域が小さな断片として分散し、それぞれの断片は小さいが、それらを合計すると十分な大きさがあるにも関わらず、大きなメモリ領域を確保できない状態。
内部断片化
メモリを確保する際に、必要なサイズよりも大きなブロックが割り当てられ、その余分な部分が無駄になる状態。
エラー:アウトオブメモリー
必要なメモリがない場合や、メモリリークによりメモリが開放されていない場合などに発生する。
まとめ
だいぶ今更感のある内容ですが、プログラミング言語での開発のみならずCS関連についてもが学習してまとめいきたいと思います!