Java 7 までは、JVM がそのクラスを保持するために使用されるPermGenと呼ばれる JVM メモリ内の領域がありました。Java 8では削除され、 Metaspaceと呼ばれる領域に置き換えられました。
PermGen と Metaspaceの最も重要な違いは何ですか?
私が知っている唯一の違いは、java.lang.OutOfMemoryError: PermGen space
スローできなくなり、VM パラメーターMaxPermSize
が無視されることです。
ユーザーの観点からの主な違いは、前の回答では十分に強調されていないと思いますが、Metaspace はデフォルトでそのサイズを (基盤となる OS が提供するものまで) 自動で増やしますが、PermGen は常に固定の最大サイズを持っています。JVM パラメータを使用して Metaspace の固定最大値を設定できますが、PermGen を自動増加させることはできません。
大部分は単なる名前の変更です。PermGen が導入されたとき、Java EE や動的なクラス (アン) ロードはありませんでした。そのため、クラスがロードされると、JVM がシャットダウンするまでメモリ内にスタックされたままになり、永続的な生成が行われました。現在、クラスは JVM の存続期間中にロードおよびアンロードされる可能性があるため、メタスペースは、メタデータが保持される領域にとってより理にかなっています。
どちらにもインスタンスが含まれており、どちらもClassLoader リークjava.lang.Class
に悩まされています。唯一の違いは、Metaspace のデフォルト設定では、症状に気付くまでに時間がかかることです (可能な限り自動で増加するため)。つまり、問題を解決せずに、問題を遠ざけるだけです。OTOH OS のメモリ不足の影響は、JVM PermGen の不足よりも深刻になる可能性があると思うので、大幅な改善になるかどうかはわかりません。
JVM を PermGen で使用する場合でも Metaspace で使用する場合でも、動的なクラスのアンロードを行う場合は、クラスローダー リークに対する対策を講じる必要があります。たとえば、私のClassLoader Leak Prevention ライブラリを使用します。
さようなら、PermGen、こんにちはメタスペース
PermGenは完全に削除されました。
メタスペース ガベージ コレクション- クラス メタデータの使用量がMaxMetaspaceSize
.
保持されていたスペースMetadata
は、 に連続していませんJava heap
。metadata
はネイティブ メモリの として知られる領域に移動しましたMetaspace
。
簡単に言えば、
クラス メタデータはネイティブ メモリから割り当てられるため、使用可能な最大容量は使用可能なシステム メモリの合計になります。したがって、遭遇することはなくなりOOM errors
、スワップスペースに流出する可能性があります.
を削除PermGen
しても、クラス ローダー リークの問題がなくなったわけではありません。したがって、はい、リークが発生するとネイティブ メモリ全体が消費されるため、消費量を監視し、それに応じて計画を立てる必要があります。
つまり、メタスペースのサイズは、制限されていない場合、クラス メタデータをロードするために必要に応じてネイティブ メモリで自動的に増加します。-XX:MaxMetaspaceSize