オブジェクトの世代を操作する

Java ガベージ コレクターは、オブジェクトを年齢ごとに分類できる世代別ガベージ コレクション戦略を実装します。

JVM におけるこのような必要性 (すべてのオブジェクトにマークを付けて圧縮する) は非効率的であると言えます。多数のオブジェクトが割り当てられると、それらのリストが増大し、ガベージ コレクション時間の増加につながります。アプリケーションの実証分析により、Java のほとんどのオブジェクトは存続期間が短いことがわかっています。

JVM のヒープ メモリ領域は 3 つのセクションに分割されています。

オブジェクトの世代を操作する

若い世代

新しく作成されたオブジェクトは若い世代から始まります。若い世代はさらに 2 つのカテゴリーに分類されます。

  • Eden Space - すべての新しいオブジェクトはここから始まり、初期メモリが割り当てられます。
  • Survivor Spaces (FromSpace および ToSpace) - オブジェクトは、1 つのガベージ コレクション サイクルを生き延びた後、Eden からここに移動されます。

オブジェクトが若い世代からガベージ コレクションされるプロセスは、マイナー ガベージ コレクション イベントと呼ばれます。

Eden のスペースがオブジェクトで満たされると、小さなガベージ コレクションが実行されます。死んだオブジェクトはすべて削除され、生きているオブジェクトはすべて残りの 2 つのスペースの 1 つに移動されます。小規模 GC は、Survivor スペース内のオブジェクトもチェックし、それらを別の (次の) Survivor スペースに移動します。

例として次のシーケンスを見てみましょう。

  1. エデンには両方のタイプ(生きているものと死んだもの)のオブジェクトがあります。
  2. 小規模な GC が発生します。すべての死んだオブジェクトが Eden から削除されます。すべての生きているオブジェクトはスペース 1 (FromSpace) に移動されます。エデンとスペース2は空になりました。
  3. 新しいオブジェクトが作成され、Eden に追加されます。エデンとスペース 1 の一部のオブジェクトは消滅します。
  4. 小規模な GC が発生します。すべての死んだオブジェクトが Eden と space-1 から削除されます。すべての生きているオブジェクトはスペース 2 (ToSpace) に移動されます。エデンとスペース-1は空です。

したがって、いつでも、生存者スペースの 1 つは常に空になります。生存者が生存者スペースを移動するための特定のしきい値に達すると、より古い世代に進みます。

-Xmnフラグを使用して、若い世代のサイズを設定できます。

古い世代

かなりの期間 (たとえば、プログラムの存続期間のほとんど) 存続するオブジェクトは、最終的には古いオブジェクト、つまり 100 歳以上のオブジェクトになります。これは通常の世代としても知られており、Survivor Spaces に長期間放置されたオブジェクトが含まれています。

オブジェクトの存続期間のしきい値によって、オブジェクトが古い世代に移動されるまでに通過する必要があるガベージ コレクション サイクルの数が決まります。オブジェクトが古い世代からガベージに送られるときのプロセスは、メイン ガベージ コレクション イベントと呼ばれます。

-Xmsフラグと-Xmxフラグを使用して、初期および最大ヒープ メモリ サイズを設定できます。

Java は世代別ガベージ コレクションを使用するため、オブジェクトが経験するガベージ コレクション イベントが増えるほど、オブジェクトはヒープ上でより遠くに移動します。彼は若い世代から始まり、十分に長く生きれば最終的には一般の世代に終わります。

スペース間および世代間でのオブジェクトの昇格を理解するには、次の例を考えてください。

オブジェクトが作成されると、それはまず若い世代のエデン空間に配置されます。

小規模なガベージ コレクションが発生するとすぐに、Eden の生きたオブジェクトが FromSpace に移動されます。次のマイナー ガベージ コレクションが発生すると、エデンと宇宙の両方の生きたオブジェクトが ToSpace に移動されます。

このサイクルは一定回数継続します。この時点以降もオブジェクトがまだ「サービス中」である場合、次のガベージ コレクション サイクルでオブジェクトは古い世代の領域に移動されます。

永続的な生成とメタスペース

クラスやメソッドなどのメタデータは永続的な生成で保存されます。JVM は、アプリケーションで使用されるクラスに基づいて実行時にこれを設定します。使用されなくなったクラスは、永続的な世代からガベージに移行する可能性があります。

-XX:PermGen フラグ-XX:MaxPermGenフラグを使用して、永続世代の初期サイズと最大サイズを設定できます。

メタスペース

Java 8 以降、PermGen 空間は MetaSpace メモリ空間に置き換えられました。実装は PermGen とは異なります。このヒープ領域は自動的に変更されるようになりました。

これにより、PermGen のヒープ領域のサイズが制限されているために発生するアプリケーションのメモリ不足の問題が回避されます。メタスペース メモリはガベージ コレクションでき、メタスペースが最大サイズに達すると、使用されなくなったクラスは自動的にクリーンアップされます。