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