「Java Memory Management」を読む会(第2回)の予習
世代別ヒープ管理
- 若い世代(Young generation)は、さらにEdenと2つのSurvivor space(S0, S1)に分かれる
- S1がターゲット空間とする
- EdenのライブオブジェクトがS1にコピーされ、年齢が1にセット
- S0のライブオブジェクトのうち年齢が閾値(MaxTenuringThreshold)を超えたものが旧い世代(Old generation)にコピーされる
- S0の残るライブオブジェクトはS1にコピーされ、年齢が1つ加算
マイナー(若い世代の)GCの発動
- Edenに新しいオブジェクトを割当てる連続した空き領域がない場合
関連するJVMフラグ
ヒープの大きさ、若い世代と古い世代の大きさの指定に関するJVMフラグがあります。
- -Xms, -Xmx はヒープの最小、最大サイズを指定
- -XX:NewSizeと-XX:MaxNewSizeは若い世代の最小サイズと最大サイズを指定
- -XX:SurvivorRationは、edenの大きさに対する2つのsurvivorの相対的なサイズを指定
- -XX:NewRationは、旧い世代に対する新しい世代の相対的なサイズを指定
- -XX:PretenureSizeThresholdは、オブジェクトのサイズがこの閾値より大きい場合にオブジェクトを若い世代ではなく直接旧い世代に割当てる
一般には、ヒープ全体の25-33%を若い世代のサイズとするとのこと。
ガベージコレクション
オブジェクトが不要となる判断(マーク)
- ストップ・ザ・ワールドは、マーキングフェーズ中に新しいオブジェクトが作成されないようにアプリケーションの実行を一時停止します。
- ストップ・ザ・ワールド以外のアプローチとして参照カウントはオブジェクトの参照数をカウントし、参照数が0となったオブジェクトを削除可能とします。アプリケーションを一時停止する必要はないですが、相互参照する孤立したオブジェクトを削除できない欠点があります。
スイープ
通常のスイープは、マークされていないオブジェクトをメモリから削除します。オブジェクトの大きさはまちまちなので、削除したメモリに新しいオブジェクトが割当てられるかはそのサイズによります。このようにメモリが断片化すると空きメモリは合ってもオブジェクトが割当てできないという問題が生じます。
断片化したメモリを、割当済みのメモリを詰めて再配置するコンパクションを行うことで解消します。ただし、コンパクションには時間がかかります。
コピーによるスイープは、メモリを2つのブロックに分け、片方のブロックに割当てられたオブジェクトのうち到達可能なライブオブジェクトをもう一つのブロックにコピーすることで断片化を防ぎます。コンパクションよりも性能がよいのもメリットですが、メモリを多く使用するのがデメリットです。
メタスペース
- クラスファイルのメモリイメージ
- クラスのstructure、method
- 定数プール
- アノテーション
- 最適化
JVMのメモリ管理の構成と監視
プロファイリングツール、jstat, jmap, VisualVM