【发布时间】:2012-05-03 17:08:25
【问题描述】:
和往常一样,问题描述很长。
我们目前正在对我们的产品进行压力测试 - 现在我们面临一个奇怪的问题。一到两个小时后,堆空间开始增长,应用程序稍后会死掉。
分析应用程序显示大量的 Finalizer 对象,填充堆。好吧,我们认为“可能是奇怪的终结器线程减慢”问题,并审查了减少需要终结的对象数量(在这种情况下为 JNA 原生句柄)。无论如何都是好主意,减少了数千个新对象...
接下来的测试显示了相同的模式,仅在一小时后并且没有那么陡峭。这次 Finalizer 源自在测试平台中大量使用的 FileInput- 和 FileOutput 流。所有资源都已关闭,但终结器不再清理。
我不知道为什么在 1 或 2 小时后(无例外)FinalizerThread 似乎突然停止工作。如果我们在某些线程中手动强制 System.runFinalization(),则分析器显示终结器已被清理。立即恢复测试会为终结器分配新的堆。
FinalizerThread 还在,询问 jConsole 他在等待。
编辑
首先,用 HeapAnalyzer 检查堆没有发现任何新的/奇怪的东西。 HeapAnalyzer 有一些不错的功能,但一开始我遇到了困难。我正在使用 jProfiler,它带有很好的堆检查工具,并且会一直使用它。
也许我错过了 HeapAnalyzer 中的一些杀手级功能?
其次,今天我们使用调试连接而不是分析器来设置测试 - 系统现在稳定了近 5 个小时。这似乎是太多终结器(在第一次审查中已减少)、分析器和 VM GC 策略的非常奇怪的组合。由于目前一切正常,没有真正的见解......
到目前为止,感谢您的意见 - 也许您会继续关注并感兴趣(现在您可能有更多理由相信我们不会谈论简单的编程错误)。
【问题讨论】:
-
终结者确实不可靠。避开他们。
-
@Charles 我这样做了,谢谢。我认为(认为)我对 GC 细节足够流利(直到现在)。在这里,我什至不是在实现“finalize”——我们谈论的是文件流......
-
@Louis 我担心有人会这样说 :-) 我会把它转发给 oracle...
标签: java out-of-memory finalizer