JVMのメモリ構造

Javaのメモリ領域の使い方を纏めたいと思います。
JavaはJVM上で動作します。Javaのメモリの使い方を考えるときには
JVMのメモリ構造を理解する必要があります。
JVMのメモリ構造はヒープとスタックの2つに大別されます。

1.Javaスタック

スタックとは積み上げていくデータ構造のことです。
Javaスタックでは、フレームを積み上げるときにこの仕組みをとっています。
フレームとはメソッドを呼び出すごとにひとつずつ確保されるもので、
フレームの中身はメソッド内のローカル変数の領域とオペランドスタック
(計算中の値を積んでおくところ)です。

Javaスタックはスレッド毎に割り当てられ、後に入れたものを先に出す(LIFO)の
待ち行列の仕組みで、固定長の線形データ構造です。
なお、メソッドを抜けたときにローカル変数の領域は解放されます。

スタックが使用されるケースとして例外発生時があります。
Javaのプログラム実行時に例外が発生したときにcatchブロックを検索しますが、
実行したメソッド内にcatchブロックが見つからない場合、さらにスタックを
さかのぼって呼び出し元メソッドのcatchグロックが検索されます。

2.ヒープ

ヒープ(Heap)とはJVM起動時に割り当てられる広大な領域です。
クラスのインスタンス(オブジェクト)を格納する領域です。
newする毎に必要な領域がヒープに確保されています。
newすると、そのオブジェクトを変数に格納すると思います。
ですので、変数がnewしたオプジェクトが存在するヒープ領域を参照しています。
よって、1で説明したJavaスタックとの関連を考えると、ローカル変数が
ヒープ領域へのポインタを保持していることになります。

また、ヒープはGCの対象になります。
(※ただし、各クラスのstaticフィールドについてはこのヒープ領域に
確保されていますが、GC対象とはなりません。
また、そのクラスが必要になったときに初めてメモリに確保されるので、
起動時間が短縮できます。=起動時に確保されていない)

参考URL:
http://msugai.fc2web.com/java/perform/storage.html

ここで、GCについても説明したいと思います。
GC(Garbage Collector)は不要になったオブジェクトのメモリの解放を自動的に行ってくれます。
不要なオブジェクトの定義ですが、以下になります。

・Javaスタック、staticフィールドからポインタを追いかけてたどることができるかどうか。

なぜ、このような定義になるかというとスタックからもstaticフィールドからも
たどれないものは絶対に参照は不可能ということになるからです。
考えてみると当たり前なのですが・・・。

ヒープにあるオブジェクトをGCの対象にしたいということであれば、
その変数にnullを代入して、参照をきってあげればOKです。

Javaコンパイルオプション

Javaは様々な言語のキャラクタセットに対応できるように、16ビットのUnicodeキャラクタにしています。
UnicodeにはASCIIで定義されている英数字や記号に割り当てられた文字コードをそのまま引き継いでいるため、英数字と記号を使っている限りは問題ないのですが、日本語を使う場合は、その文字エンコーディングをUnicode(UTF-8)に変換する必要があります。

javacでコンパイルオプション「-encoding」を指定する場合がありますが、これはOS標準のエンコーディング(WindowsはShift JIS、UNIXでは日本語EUC)と同じであれば自動的に標準の文字エンコーディングから変換を行うのでこのオプションを意識する必要はありませんが、標準と異なるエンコーディングを使用している場合は、javacに「-encoding」のオプションを指定する必要があります。

※ただしコンパイル前にJavaのソースコードをUnicodeに変換する必要がある。