2

Groovyクラスをカスタムロードするために使用しているJavaでカスタムクラスを作成しました。

私のJavaクラスは次のように始まります。

public class ClassLoader {
    private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();

次に、を使用しgroovyClassLoaderてクラスを名前でロードするメソッドがあります。

Class c = groovyClassLoader.loadClass(className, true, false, true);

これはすべて正常に機能しており、問題はありません。ただし、Groovyクラスをすべて動的にリロードしたい場合があるため、現時点では、Javaコードは基本的にインスタンスを再インスタンス化しClassLoaderます。これにより、インスタンスへの参照が残りなくなりClassLoader、予想どおりにGCされます。

ただし、ロードされたクラスを(VisualVMとMATを使用して)数回リロードした後に調べると、JavaクラスClassLoaderが1回だけロードされ、インスタンスが1つだけであることがわかりますが、いくつかのインスタンスがありますGroovyClassLoader$InnerLoader(この場合、クラスは1回ロードされますが、いくつかあります)インスタンス)およびロードされたいくつかのクラスGroovyClassLoaderGroovyClassLoader$1GroovyClassLoader$2など)

ClassLoaderJavaが収集されているにもかかわらず、GroovyClassLoaderとそのInnerLoaderが収集されていない理由はありますか?

ありがとう!

4

2 に答える 2

2

c名前でロードしたクラスの1つのインスタンスである到達可能なオブジェクトがまだいくつかあるのではないでしょうか。すべてのクラスは、その定義クラスローダーへの参照を保持しているため、ロードしたすべてのクラスのすべてのインスタンス自体が到達不能になるまで、クラスローダーをGCdすることはできません。

これが十分でない場合は、GroovyMetaClassメカニズムが問題である可能性があります。インスタンスMetaClassRegistryの使用が終了したら、クラスを明示的に削除する必要がある場合があります。com.example.ClassLoader

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

Groovyがあなたに代わってこれを行うことを期待していましたが、デフォルトで望んでいるよりも積極的になる必要があるかもしれません。

于 2013-01-15T18:06:20.210 に答える
1

PlayフレームワークでのGroovyテンプレートエンジンに関する最近の経験から、Groovyは、コンパイルされたクラスがアプリケーションコードから到達できない場合、メタクラスレジストリをクリーンアップしません。

https://hoangx281283.wordpress.com/2014/07/24/unload-groovy-classes/

于 2014-07-25T01:56:31.743 に答える