私はカスタムクラスローダーでGroovyクラスを動的にリロードするJavaクラスを持っていますが、一部のクラスでは収集されないという奇妙な動作が見られますが、メモリ(例えば、perm genは無期限に成長しません)。私のJavaコードでGroovyクラスは収集されていませんが、メモリリークの兆候はありません
は、私はそう(単純化のために削除定型のもの)のようなクラスをロードしています:
Class clazz = groovyClassLoader.loadClass(className, true, false, true);
instance = clazz.newInstance();
そして私は、クラスローダキャッシュ、metaregistryなどクリアしてGroovyクラスを動的にリロード:
をfor (Class c : groovyClassLoader.getLoadedClasses()){
GroovySystem.getMetaClassRegistry().removeMetaClass(c);
}
groovyClassLoader.clearCache();
このコードを繰り返しループしていて、Groovyクラスを常にロードしてから再読み込みすると、奇妙な動作が発生します(テストコードは文字通りリロードプロセスをループしています。作成されたオブジェクトなど、インスタンス上のコードではローカルなのでGCには良いはずです)。
私は128メートルにMaxPermSizeの設定、それを実行した場合、私は行動を漏らす取得し、それがエラーをpermgen OOM:
私は再びそれを実行し、256メートルにMaxPermSizeのを増やす場合は、その後、すべてがあります良い、それは(この画像は1時間ですが、私はリロードの数千人をやって一晩それを実行している)永遠に実行することができます。
誰もが任意の同様の現象に遭遇していますか?または任意のアイデアがありますか?また、最初の例では、メモリ使用量が着実に増加するのではなく、段階的に増加していることは奇妙に思えます。
あなたの256m permダイアグラムは、あなたのプログラムが150M permを実行する必要があることを示しています。私のアプリでは、漏れを防ぐためにgroovyを.classにコンパイルします。しかし、メタクラスはまたpermgen(約100m)の多くを取った – farmer1992
@ farmer1992 - はい、しかし、私はいつでも256シナリオでheapdumpを取る場合は、いくつかの重複したクラスが表示されますが表示されますその時点でロードされている各Groovyクラスの〜20バージョンがあることを確認してください)。また、128グラフでは、行の各ステップが多かれ少なかれリロードに相関しているので、セット全体をリロードすると〜5MBのような形でpermgenが増加することがわかります – rhinds