我正在开发一个应用程序,它的目的是尽可能快地计算报告。
我的应用程序使用了大量内存,超过100 Go。
自上一次发布以来,我注意到性能大幅下降。我的调查显示,在计算过程中,我得到了40到60秒的垃圾收集!(JMC告诉我它们是SerialOld,但我不知道它到底意味着什么),当然,当JVM正在垃圾收集时,应用程序被完全冻结了。
我现在正在调查垃圾收集的起源..。这是一项非常艰苦的工作。
我怀疑,如果这些垃圾收集时间太长,那是因为它们在finalize函数中花费了很多时间(我知道,在我们从其他团队集成的所有库中,有些库使用终结器)
然而,我不知道如何简化(或不)这个假设;如何找到哪一个终结器是耗时的。
我正在寻找一个好的工具,甚至是一个好的方法。
以下是通过JVisualVM收集的数据

如您所见,当我有一个日志旧垃圾时,我总是有许多“挂起的终结器”
令人惊讶的是,当我使用JVisualVM时,上面的图表会从右到左定期滚动。当触发旧垃圾时,滚动停止(直到这里,它看起来很正常,这是世界末日)。但是,当滚动突然重新启动时,它不是从旧垃圾结束,而是从挂起的序列化程序结束
这让我认为终结器阻塞了JVM。
有人对此有解释吗?
非常感谢菲利普
发布于 2016-11-13 08:09:00
我的应用程序使用了大量内存,超过100 Go。 JMC告诉我他们是SerialOld,但我不知道这到底意味着什么
如果您将串行收集器用于一个100 of的堆,那么需要长时间暂停,因为串行收集器是单线程的,而且一个内核每单位时间只能占用这么多内存。
只要选择多线程收集器中的任何一个,就会产生较低的暂停时间。
然而,我不知道如何简化(或不)这个假设;如何找到哪一个终结器是耗时的。
一般情况下:收集更多数据。对于与GC相关的事情,您需要启用GC日志记录,对于在java代码中花费的时间(无论是您的应用程序还是第三方库),您需要一个分析器。
发布于 2016-11-12 12:23:23
这是我要做的来调查你的终结理论。
现在,您可以使用分析器信息来确定哪些(如果有的话) finalize方法正在使用大量时间。
然而,我怀疑真正的问题将是内存泄漏,您的JVM已经到了堆满不可收回对象的地步。这可以解释为什么频繁的"SerialOld“垃圾回收。
或者,这可能只是一个大堆问题。100 is是..。大的。
https://stackoverflow.com/questions/40562665
复制相似问题