回答:
更新この回答は、Java 5-7に関連している、Javaの8は、この固定がありますhttps://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace賞賛に行くメートル。うーる
Java 5-7の場合:
世界の標準的なOracle / Sun VMの外観は次のとおりです。クラスは永遠です。したがって、一度読み込まれると、誰も気にしなくてもメモリに残ります。純粋に「セットアップ」クラスはそれほど多くないので、これは通常は問題ありません(=セットアップに一度使用され、その後は二度と使用されません)。したがって、1MBを占有する場合でも、問題ありません。
しかし最近では、実行時にクラスを定義するGroovyのような言語があります。スクリプトを実行するたびに、1つ(または複数)の新しいクラスが作成され、PermGenに永久に残ります。サーバーを実行している場合は、メモリリークがあることを意味します。
CMSClassUnloadingEnabled
GC を有効にすると、PermGenもスイープし、使用されなくなったクラスが削除されます。
[編集]有効にする必要もありますUseConcMarkSweepGC
(Sam Haslerに感謝)。この回答を参照してください:https : //stackoverflow.com/a/3720052/2541
-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC
。UseConcMarkSweepGC
有効にする必要がありますCMSClassUnloadingEnabled
。」
ブログ投稿によると、Java JVMの-XXオプションの最も完全なリストは、CMSガベージコレクターの下でクラスのアンロードが有効かどうかを決定します。デフォルトはfalse
です。呼ばれる別のオプションがありますClassUnloading
ですtrue
(おそらく)他のガベージコレクタに影響を与え、デフォルトでは。
以前にロードされたクラスがJVMのどこでも使用されなくなったことをGCが検出すると、クラスのバイトコードやネイティブコードを保持するために使用されていたメモリを解放できるという考え方です。
CMSClassUnloadingEnabledを設定すると、可能性があなたのpermgenの問題に役立つあなたが現在CMSコレクタを使用している場合。しかし、可能性は、CMSを使用していないか、または本物のクラスローダー関連のメモリリークがあることです。後者の場合、クラスが未使用であるようにGCに表示されることはないため、アンロードされることはありません。
アーロン・ディグラは「クラスは永遠に続く」と言います。これは、純粋にJavaの世界でさえ、厳密には当てはまりません。実際、クラスの存続期間はクラスローダーに関連付けられています。したがって、クラスローダーがガベージコレクションされるように調整できる場合(そして、それが常に簡単なことではない場合)、ロードしたクラスもガベージコレクションされます。
実際、これは、webappのホット再デプロイを行うときに起こります。(または、少なくとも、permgenのストレージリークにつながる問題を回避できれば、それが起こるはずです。)
これが役立つ例:
-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
Weblogic 10.3 JVMを設定すると、JAX-WS実装がすべてのWebサービス呼び出しに対して新しいプロキシクラスを作成し、最終的にメモリ不足エラーが発生する問題の解決に役立ちました。
トレースするのは簡単ではありませんでした。次のコードは常に同じプロキシクラスを返しましたport
final MyPortType port =
Service.create(
getClass().getResource("/path/to.wsdl"),
new QName("http://www.example.com", "MyService"))
.getPort(
new QName("http://www.example.com", "MyPortType"),
MyPortType.class);
内部的には、このプロキシはのインスタンスにweblogic.wsee.jaxws.spi.ClientInstance
委任されており、再び、呼び出しごとに増分される新しい$Proxy[nnnn]
クラスに委任されましたn
。フラグを追加すると、n
はまだ増加していましたが、少なくともそれらの一時クラスはメモリから削除されました。
より一般的な注意として、これは、Javaリフレクションとプロキシを多用する場合に非常に役立ちます。 java.lang.reflect.Proxy
-XX:+CMSPermGenSweepingEnabled
が非推奨であることにも注意してください-XX:+CMSClassUnloadingEnabled
CMSClassUnloadingEnabled
、影響を与えるためにUseConcMarkSweepGC
も設定する必要があります