4

これは前の質問の続きです: Using GroovyClassLoader from Java - Classes not GC'd

私は以前、カスタム groovy クラスローダーを使用して Java 環境で Groovy クラスをロードしていました。それらを正しく GC するために、次のようにメタ クラス レジストリを明示的にクリアする必要がありました。

for(Class<?> c : groovyClassLoader.getLoadedClasses()) {
    GroovySystem.getMetaClassRegistry().removeMetaClass(c);
}

通常のJavaクラスローダーを介してロードしているJARにgroovyクラスをプリコンパイルすることに切り替えましたが、更新されたクラスを再ロードしようとすると、perm genメモリリークが再び発生するようになりました。

私のクラスをGCするために何か特別なことをする必要があるかどうか誰でも知っていますか? 実行時にいくつかのグルーヴィーにコンストラクター/メソッドを動的に追加しているので、まだmetaClassRegistryをクリアする必要があると思いますか?

groovyClassLoader を使用しなくなったため、上記のコードは (明らかに) 機能しませんが、metaClassRegistry を繰り返してみたところ、レジストリに対して null が返されました。

    def metaClasses = GroovySystem.getMetaClassRegistry().iterator()
    while( metaClasses.hasNext()){
        def thisGuy = metaClasses.next()
        GroovySystem.getMetaClassRegistry().removeMetaClass(thisGuy)
    }
4

1 に答える 1

1

同じ問題でしたが、MetaClassRegistry に到達するために別のルートが必要でした。次のコードは仕事をしました:

def registry = metaClass.getRegistry()
def iterator = registry.iterator()
while ( iterator.hasNext() ){
    def mc = iterator.next()
    registry.removeMetaClass( mc.getJavaClass() )
}

(これはコンパイルされた groovy クラスの 1 つから呼び出されるため、同じクラスローダー/metaClassRegistry を使用していることに注意してください)

于 2013-07-30T16:52:14.070 に答える