Java言語ではインスタンス変数やクラス変数といった変数が存在しています。
それぞれがどのような変数で、どのようにメモリ管理がされているかを確認しておきましょう。
インスタンス変数
基本データ型変数
まずは一番最初に学習することが多い基本データ型を見ていきます。
コードのイメージとしては
int a = 1;
などですね。
これは「スタック領域」と呼ばれるメモリ領域に、int型の箱を用意して、「1」という整数値を入れているイメージです。
スタック領域
スタック領域とは下記のような特徴があります。
スタックという文字の通り、実行される場合はこの領域に、格納され、終わるとここから取り除かれる。1スレッドで1つの領域が使われる。
値型はここに格納される。
特定のスコープのみに対して使用されるため、メモリ管理がしやすい反面、大きいデータの格納には向いていない。
オブジェクトのデータはポインタがここに格納され、実データは後述するヒープ領域で管理される。
参照型変数
次に参照型変数を見ていきます。
オブジェクトを扱う変数(基本データ型以外の変数)は参照型変数になります。
コードのイメージとしては
Integer i = new Integer();
Integer j = i;
などですね。
オプジェクト自体は「ヒープ領域」に作成され、そのオブジェクトのポインタが「スタック領域」にある変数に格納されています。
配列も参照型変数になるため、同じイメージになります。
int[] a = new int[5];
ヒープ領域
ヒープ領域とは下記のような特徴があります。
開始時に一定領域確保され、必要の都度アプリケーションに割り当てられる。
大きいデータ、スコープがはっきりしないもの、サイズが動的なデータなどの格納に向いている。
領域が動的な代わりに少し遅い。
全アプリケーションで1つ。
クラスの実態はこの領域に実データが格納される。
クラス変数
static変数(静的変数)
最後にstatic変数(静的変数)を見ていきます。
コードのイメージとしては
class Test { static int num = 2; } class Main { Test t1 = new Test(); Test t2 = new Test(); }
などです。(static変数なので、実際にはインスタンス化する必要がありませんが)
前に説明したのと同じく、オブジェクト自体は「ヒープ領域」に作成され、そのポインタが「スタック領域」の変数に格納されます。
ただし、static変数はさらに別の「静的領域」に格納されることになります。
そのため、static変数の値はインスタンス毎に持つのではなく、アプリケーション共通の値になります。
静的領域
静的領域とは下記のような特徴があります。
読んで字のごとく、プログラムが開始されて、終了するまで固定的な領域。
グローバル変数やコード自体などはここに格納される。全アプリケーション共通の領域。
まとめ
インスタンス変数とクラス変数がそれぞれどのような変数で、どのようにメモリ管理されているかを見てきました。
ちょっと複雑なところもあるかと思いますが、多くのプログラムを書くことで少しずつでもイメージを捉えられるようになっていきましょう。