我在java中创建了一个自定义类,用于自定义加载Groovy类。
我的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),我会看到ClassLoader只加载了一次,只有一个实例,但是有几个GroovyClassLoader$InnerLoader的实例(在本例中是一次加载的类,但有几个实例)和几个为GroovyClassLoader加载的类(如GroovyClassLoader$1、GroovyClassLoader$2等)。
您知道为什么尽管收集了Java ClassLoader,却没有收集GroovyClassLoader及其InnerLoader吗?
谢谢!
发布于 2013-01-16 02:06:20
也许仍然有一些可到达的对象是您按名称加载的某个类c的实例?每个类都有一个对其定义类加载器的引用,因此类加载器只有在它加载的所有类的所有实例本身都变得不可访问时才能为GCd。
如果这还不够,那么问题可能出在Groovy的MetaClass机制上。在完成com.example.ClassLoader实例后,您可能需要显式地从MetaClassRegistry中删除类:
public void destroy() {
for(Class<?> c : groovyClassLoader.getLoadedClasses()) {
GroovySystem.getMetaClassRegistry().removeMetaClass(c);
}
}我本来希望Groovy为您做这件事,但您可能需要比默认情况下更主动一些。
发布于 2014-07-25 09:56:32
根据我最近在Play框架中使用Groovy模板引擎的经验,当Groovy编译的类无法从应用程序代码中访问时,Groovy不会清理Meta Class Registry。
https://hoangx281283.wordpress.com/2014/07/24/unload-groovy-classes/
https://stackoverflow.com/questions/14343393
复制相似问题