首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java中的GroovyClassLoader - Classes未进行GC

使用Java中的GroovyClassLoader - Classes未进行GC
EN

Stack Overflow用户
提问于 2013-01-16 01:32:13
回答 2查看 2.5K关注 0票数 2

我在java中创建了一个自定义类,用于自定义加载Groovy类。

我的Java类是这样开始的:

代码语言:javascript
复制
public class ClassLoader {
    private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();

然后我有一个方法,它使用groovyClassLoader按名称加载类:

代码语言:javascript
复制
Class c = groovyClassLoader.loadClass(className, true, false, true);

这一切都工作得很好,没有问题。但是,我有时想动态地重新加载所有Groovy类,所以目前我的java代码基本上只是重新实例化我的ClassLoader实例。这将不会留下对ClassLoader实例的剩余引用,正如您所期望的,这是GC定义的。

但是,如果我在几次重新加载之后检查加载的类(使用VisualVM和MAT),我会看到ClassLoader只加载了一次,只有一个实例,但是有几个GroovyClassLoader$InnerLoader的实例(在本例中是一次加载的类,但有几个实例)和几个为GroovyClassLoader加载的类(如GroovyClassLoader$1GroovyClassLoader$2等)。

您知道为什么尽管收集了Java ClassLoader,却没有收集GroovyClassLoader及其InnerLoader吗?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-16 02:06:20

也许仍然有一些可到达的对象是您按名称加载的某个类c的实例?每个类都有一个对其定义类加载器的引用,因此类加载器只有在它加载的所有类的所有实例本身都变得不可访问时才能为GCd。

如果这还不够,那么问题可能出在Groovy的MetaClass机制上。在完成com.example.ClassLoader实例后,您可能需要显式地从MetaClassRegistry中删除类:

代码语言:javascript
复制
public void destroy() {
  for(Class<?> c : groovyClassLoader.getLoadedClasses()) {
    GroovySystem.getMetaClassRegistry().removeMetaClass(c);
  }
}

我本来希望Groovy为您做这件事,但您可能需要比默认情况下更主动一些。

票数 2
EN

Stack Overflow用户

发布于 2014-07-25 09:56:32

根据我最近在Play框架中使用Groovy模板引擎的经验,当Groovy编译的类无法从应用程序代码中访问时,Groovy不会清理Meta Class Registry。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14343393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档