我一直在与一些内存泄漏作斗争,我目前对这个问题感到困惑.有一个Web应用程序类加载器,应该是垃圾收集,但它不是(即使我修复了几个泄漏).我用jmap转储堆并用jhat浏览它,找到了类加载器并检查了rootset引用.
如果我排除弱参考,列表是空的!这怎么可能,因为只有弱引用持有的对象应该收集垃圾?(我在jconsole中多次执行GC)
如果我包含弱引用,我会得到一个引用列表,所有引用都来自以下某个字段:
java.lang.reflect.Proxy.loaderToCache
java.lang.reflect.Proxy.proxyClasses
java.io.ObjectStreamClass中的$ Caches.localDescs
java.io.ObjectStreamClass中的$ Caches.reflectors
java.lang.ref.Finalizer.unfinalized
我找不到任何理由为什么这些引用应该防止垃圾收集类加载器.这是一个gc bug吗?特殊无证案件?jmap/jhat bug?或者是什么?
最奇怪的是......在闲置和闲逛之后大约40分钟,没有改变任何东西,它最终决定卸载类并收集类加载器.
注意:
如果您对延迟收集类加载器或弱引用提出声明,请说明发生的情况,理想情况是:
提供指向支持您的声明的权威文章的链接
提供演示行为的示例程序
如果您认为该行为是依赖于实现的,那么请关注oracle或icedtea jvm版本6或7中发生的事情(选择其中任何一个并具体说明).
我真的想深究这一点.我实际上已经花了一些力气来重现测试程序中的问题,但我失败了 - 除非有强烈的引用,否则每次都会立即在System.gc()上收集类加载器.