メインコンテンツまでスキップ

値型・参照型

  • 値型:

    • 値型(例えば intfloat など)はスタックに保存されます。スタックに直接データが格納され、スコープを抜けると自動的に解放されます。
  • 参照型:

    • 参照型(例えばクラスや配列)はヒープにデータが格納され、その参照(アドレス)だけがスタックに保存されます。ヒープ上のオブジェクトは、ガベージコレクションが不要と判断したときに解放されます。

  • 値型 → スタックに直接保存。
  • 参照型 → ヒープにデータが保存、スタックにその参照が保存。





スタック・ヒープ

スタック(Stack)ヒープ(Heap) は、プログラムがメモリを管理する際に使用される領域の2つの異なる方法です。
それぞれの特徴と役割を解説します。



1. スタック(Stack)

スタックは、 LIFO(Last In, First Out) 方式でメモリを管理する領域です。主に関数のローカル変数や、メソッド呼び出し時の情報(戻り先アドレスやパラメータなど)を保存します。

特徴:

  • 高速アクセス: スタックはメモリの領域を一括で管理するため、変数の割り当てや解放が非常に高速です。
  • 自動管理: 変数はスコープを抜けると自動的に解放されるため、メモリ管理がシンプルです。開発者が手動で解放する必要はありません。
  • サイズ制限: スタックは一般的にサイズが小さい(数MB程度)ため、大きなデータ(例: 巨大な配列やオブジェクト)はスタックに格納できません。

使用例:

  • 関数のローカル変数(intfloat などのプリミティブ型)
  • 関数の引数
  • 戻りアドレス(呼び出し元に戻るための情報)

イメージ:

関数が呼び出されるごとに、その関数で使用される変数や情報がスタックに積み上げられ、
関数が終了するとそれらが一気に取り除かれる(解放される)。


2. ヒープ(Heap)

ヒープ は、動的にメモリを確保するための領域です。必要に応じてプログラムの実行中に自由にメモリを確保(動的割り当て)し、使い終わったら明示的に解放する必要があります。

特徴:

  • 動的メモリ管理: ヒープは必要な分だけ動的にメモリを割り当てることができ、使用が終わったら解放する必要があります(手動解放やガベージコレクションが担当)。
  • 大きなメモリ領域: スタックに比べてヒープのサイズは大きく、巨大なデータ構造(例: 大きな配列やオブジェクト)を扱うのに適しています。
  • メモリの断片化が発生しやすい: メモリがランダムに割り当てられるため、断片化が起き、アクセス速度が遅くなることがあります。

使用例:

  • オブジェクトや配列の動的なメモリ割り当て
  • クラスのインスタンス
  • ランタイム中にサイズが決まるデータ構造

イメージ:

ヒープに割り当てたメモリは、プログラムがその領域を指すポインタを保持し、
明示的にメモリを解放するまでそのまま残る。

スタックとヒープの違い

  • 割り当て方式: スタックはLIFO(順序通りの自動解放)、ヒープは動的に割り当て・解放。
  • 管理方法: スタックは自動管理、ヒープは手動またはガベージコレクションで管理。
  • 速度: スタックはヒープよりも高速にアクセス可能。
  • サイズ: スタックは一般にサイズが小さく、ヒープはより大きなメモリ領域を持つ。

まとめ

  • スタック: 高速で自動管理されるメモリ領域、小さなデータに適している。
  • ヒープ: 大きなデータや動的なメモリ割り当てが必要な場合に利用されるが、手動解放やガベージコレクションが必要。