オブジェクト指向のメモリ領域は以下に分類されます。
メソッドエリア(静的領域)
「静的」と呼ばれる理由としては、この領域に確保された情報はプログラムの実行時には変化しないため。
確保タイミング
C言語やC++であれば、アプリケーション開始時に確保します。JavaやRuby、.NETなどは逐次メモリ上に確保します。
前者であれば、実行速度が上がりますが、メモリを食います。後者は逆です。
格納情報
グローバル変数、実行コード(クラスの情報など)
確保単位
プロセス単位(複数のスレッドから共有される)
スタック領域
スレッドごとに領域が確保されるので競合する心配はない。サブルーチンの呼び出し制御のために使用されるメモリ領域です。
ヒープ領域は複数スレッドから参照されるのに対して、スタック領域はスレッドごとに用意される領域になります。
確保タイミング
LIFO(後入れ先出し方式)
格納情報
サブルーチンの引数、ローカル変数、戻り先
確保単位
スレッド単位
ヒープ領域
プログラムの実行時に動的に確保するメモリ領域です。複数スレッドから同時に同じメモリに割り当て要求が来た場合などは整合性を保つ必要があるためプロセスやスレッドという単位ではなく、OSや仮想マシンがうまく制御して管理します。
具体的には、クラスのインスタンスの生成(new)の都度割り当てが行われ、アプリで使わなくなって不要になったら解放されます。(従来の言語ではヒープ領域を使うことはなかったのですが、Javaに代表するOOP言語ではヒープ領域を普通に使います。ハードウェア性能の向上によって実現が可能になりました。)
確保タイミング
アプリケーション開始時に一定領域を確保し、都度拡張する。
格納情報
クラスのインスタンス。
確保単位
プロセス単位(複数のスレッドから共有される)、要はアプリケーションやシステムで一つということです。
ガーベジコレクションの対象
「スタック」と「メソッドエリア(静的領域」から参照されなくなったヒープ領域のインスタンスが解放されます。要は、アプリケーションからアクセスされなくなったインスタンスを自動的に解放する仕組みなのです。
プログラマーとして気をつける点としては、不要になったインスタンスをスタックやメソッドエリアから参照し続けないようにすること。
また、メモリを使い過ぎてしまうとプログラムの動作が重くなってしまいますし、JavaのOutOfMemoryでプログラムが異常終了してしまう可能性もゼロではないです。
この記事へのコメントはありません。