djh*_*djh 5 java groovy memory-leaks classloader java-7
我运行一个Groovy/Grails系统,动态编译并加载用户定义的代码.这基本上是通过GroovyClassLoader
.
我看到动态类本身都加载和卸载就好了.我添加了
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
Run Code Online (Sandbox Code Playgroud)
旗帜,工作正常.当类加载器是GC时,动态类正在卸载.
但是我的堆内存泄漏,这是泄漏的来源:
现在,Launcher$AppClassLoader
有一个parallelLockMap
定义的属性java.lang.ClassLoader
.显然,这ConcurrentHashMap
用于在Java 7中保存并行类加载锁.查看源代码.
此映射中保留的条目具有String
键(锁定适用的类名称)和Object
值(锁定对象).有两种泄漏密钥:
"groovy.runtime.metaclass.MyDynamicallyLoadedClassNameMetaClass"
"MyDynamicallyLoadedClassNameBeanInfo"
Run Code Online (Sandbox Code Playgroud)
所以对我来说,看起来这些键是在加载和类parallelLockMap
时创建的,但是当卸载关联的动态加载的类(及其元类)时,它们不会被删除.现在,这已经深入到Groovy及其元类系统的内部,我的专业知识已经耗尽.*MetaClass
*BeanInfo
这最终会让你离开堆空间,尽管需要一段时间:
String newClass = "class CLASSNAME {}"
while (true) {
GroovyClassLoader gcl = new GroovyClassLoader()
Class clazz = gcl.parseClass(newClass.replace("CLASSNAME", "NewClass"+System.nanoTime()))
clazz.newInstance()
}
Run Code Online (Sandbox Code Playgroud)
确保使用上面的JVM标志运行它,以便用尽堆空间,而不是PermGen空间.再次,PermGen很好地收集垃圾,没有泄漏.
1)这是Groovy或Java 7中的错误吗?清洁这个是谁的责任parallelLockMap
?我应该提交问题报告吗?
2)有解决方法吗?我正在考虑使用一个自定义ClassLoader
,它不会首先尝试将类加载委托给它们的父级以用于这些MetaClass
和BeanInfo
类,从而阻止了对它的调用java.lang.ClassLoader#loadClass(..)
.不过,我不是Java/Groovy类加载方面的专家.
编辑:我在这里提交了一个Groovy JIRA .
编辑:在JDK方面,这个问题最近已在此报道.
归档时间: |
|
查看次数: |
1443 次 |
最近记录: |