我有一个 Java 类,它使用自定义类加载器动态重新加载 groovy 类,并且我看到一些奇怪的行为,某些类没有被收集,但随着时间的推移,它不会泄漏内存(例如,perm gen 不会无限期地继续增长)。
在我的java代码中,我正在加载这样的类(为了简单起见,删除了样板文件):
Class clazz = groovyClassLoader.loadClass(className, true, false, true);
instance = clazz.newInstance();
然后我通过清除类加载器缓存、元注册表等来动态重新加载 groovy 类:
for (Class c : groovyClassLoader.getLoadedClasses()){
GroovySystem.getMetaClassRegistry().removeMetaClass(c);
}
groovyClassLoader.clearCache();
现在,如果我只是循环这段代码,不断加载然后重新加载我的常规类,我会看到奇怪的行为(我的测试代码实际上只是循环重新加载过程 - 它没有对创建的任何对象等执行任何操作,所以上面代码中的实例只是本地的,所以应该有利于 GC)。
如果我运行它,将 maxpermsize 设置为 128m 然后我会出现泄漏行为并且出现 OOM permgen 错误:
但是,如果我再次运行它并将 maxpermsize 增加到 256m,那么一切都很好,它可以永远运行(此图像是 1 小时,但我已经运行了一夜,进行了数千次重新加载):
有人遇到过类似的行为吗?或者有什么想法吗?同样奇怪的是,在第一个示例中,内存使用量呈阶梯式上升,而不是稳定增加。