adi*_*tsu 11 java garbage-collection memory-leaks classloader
我一直在与一些内存泄漏作斗争,我目前对这个问题感到困惑.有一个Web应用程序类加载器,应该是垃圾收集,但它不是(即使我修复了几个泄漏).我用jmap转储堆并用jhat浏览它,找到了类加载器并检查了rootset引用.
如果我排除弱参考,列表是空的!这怎么可能,因为只有弱引用持有的对象应该收集垃圾?(我在jconsole中多次执行GC)
如果我包含弱引用,我会得到一个引用列表,所有引用都来自以下某个字段:
我找不到任何理由为什么这些引用应该防止垃圾收集类加载器.这是一个gc bug吗?特殊无证案件?jmap/jhat bug?或者是什么?
最奇怪的是......在闲置和闲逛之后大约40分钟,没有改变任何东西,它最终决定卸载类并收集类加载器.
注意:
如果您对延迟收集类加载器或弱引用提出声明,请说明发生的情况,理想情况是:
如果您认为该行为是依赖于实现的,那么请关注oracle或icedtea jvm版本6或7中发生的事情(选择其中任何一个并具体说明).
我真的想深究这一点.我实际上已经花了一些力气来重现测试程序中的问题,但我失败了 - 除非有强烈的引用,否则每次都会立即在System.gc()上收集类加载器.
看起来某处涉及软引用。这是我能找到的延迟收集(约 40 分钟)的唯一解释。我最初认为软引用会一直保留到内存耗尽,但我发现事实并非如此。
来自此页面:“软可访问的对象将在上次被引用后的一段时间内保持活动状态。默认值是堆中每空闲兆字节的生命周期一秒。可以使用 -XX:SoftRefLRUPolicyMSPerMB 调整此值旗帜”
所以我将该标志调整为 1,并在几秒钟内收集了类加载器!!
我认为软引用来自 ObjectStreamClass。问题是为什么 jhat 没有在 rootset 引用中显示它。是因为它不强也不弱吗?还是因为它已经找到了来自相同静态字段的弱引用?还是其他什么原因?无论哪种方式,我认为这需要在 jhat 中改进。
| 归档时间: |
|
| 查看次数: |
1247 次 |
| 最近记录: |