Java 基礎からマスターまで — 第9回
JVMメモリ、GC、JITの役割を理解する
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
JavaコードはJVM上で実行され、クラスのロード、メモリ管理、実行の最適化をランタイムの助けを借りて処理します。 内部用語を覚えるよりも、このプロセスがパフォーマンスとエラーにどのような影響を与えるかを理解することが重要です。
クラスローディングとバイトコード
Source.java
↓ compiler
Source.class
↓ class loader
JVM execution
クラスローダは必要なクラスを探し、JVMが利用可能な型であることを確認します。 クラスパスや依存関係が合わないと、コンパイルが成功しても実行中のクラスが見つからない可能性があります。
スタックとヒープ
メソッド呼び出し情報とローカル変数は、各スレッドの呼び出しフレームで管理されます。 複数の場所で参照できるオブジェクトは、管理対象ヒープ領域に作成されます。
void update() {
int damage = 10;
Monster monster = new Monster();
monster.takeDamage(damage);
}
damageは基本型の値で、monster変数はオブジェクト参照です。 実際の配置と最適化はJVM実装が決定するので、すべてのオブジェクトの位置を単純な公式で判断しないでください。
Garbage Collector
もはや到達不能なオブジェクトはGCの収集の対象となります。 GCがあるということは、メモリリークが絶対にないという意味ではありません。
未使用のオブジェクトを static コレクションまたはイベントリスナーが参照し続けると、到達可能なままになります。 ファイルやソケットなどの外部リソースは、GCを待たずに直接閉じる必要があります。
JIT最適化
JVMは実行中によく使われるコードを観察し、機械語でコンパイルして最適化することができる。 短い1回の実行時間で全体のパフォーマンスを判断すると、準備プロセスと最適化状態が混在する可能性があります。
パフォーマンスの問題は、ヒープサイズやGCオプションから変更する前に、クォータ、CPU使用率、ロック待機をプロファイラで測定する必要があります。 JVMの知識は推測で微細最適化するためではなく、測定結果の原因を解釈するための基盤である。