java - 使用 Java 中的 GroovyClassLoader - 未 GC 的类

标签 java memory-leaks groovy classloader

我在 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),我会看到 Java 类 ClassLoader 仅加载了一次,只有一个实例,但有多个实例GroovyClassLoader$InnerLoader(在本例中,类加载一次,但有多个实例)以及为 GroovyClassLoader 加载的多个类(例如 GroovyClassLoader$1GroovyClassLoader$2 等)

有什么想法为什么尽管 Java ClassLoader 被收集,但 GroovyClassLoader 及其 InnerLoader 没有被收集?

谢谢!

最佳答案

也许仍然有一些可访问的对象是您按名称加载的类 c 之一的实例?每个类都保存对其定义类加载器的引用,因此在它加载的所有类的所有实例本身变得无法访问之前,该类加载器无法被 GCd。

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

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

我本希望 Groovy 为您做到这一点,但您可能需要比默认情况下更加主动。

关于java - 使用 Java 中的 GroovyClassLoader - 未 GC 的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14343393/

相关文章:

java - GWT 网格表选项卡顺序

java - 如何使用cglib实现委托(delegate)?

java - 2个不同依赖问题中的相同接口(interface)

c++ - parallel_for 函数导致内存泄漏(有时)

java - 使用 Swing 将 Jpanels 正确添加到 BoxLayout 时遇到问题

c - 没有 mmap2 系统调用 strace 的内存分配?

memory-leaks - 如何释放为 Crystal 中的某些结构分配的内存 - 手动?

windows - Groovy 无法在 Windows 7 64 上启动

testing - 在grails集成测试中重写服务方法

java - 如何使用 NiFi 中的新 DBCPConnectionPoolLookup 列出一组数据库中的数据库表?