我的应用程序在两个环境中工作正常,但在验收测试环境中存在内存泄漏。 JVM堆转储显示堆满98%的java.object.finalize()(如果我没记错的话.GC日志表明GC正在越来越频繁地执行Full GC,直到JVM给出Out of Memory -error。
可能导致这种情况的原因是什么?应用程序在所有环境中都是相同的,但操作系统和网络在问题环境中略有不同。 Java在所有环境中都是相同的。这个输出甚至意味着什么,GC已经调用了Object Finalize(),但由于某些原因它没有完成?我正在使用JBoss EAP 5。
答案 0 :(得分:1)
有可能创建需要最终确定的垃圾,而不是最终确定。当确定一个对象无法访问(即,有资格收集)并需要完成时,它将被添加到终结器队列而不是立即收集。在完成终结器后的下一个GC上,可以收集对象。换句话说,最终确定会延迟内存的恢复。
有一个线程执行所有finalize方法,默认情况下它以与所有其他线程相同的优先级运行。如果有许多线程创建需要完成的垃圾,它们可以比一个终结器线程执行finalize()
方法更快地生成垃圾。此外,如果你最终确定方法不快,你只会让这个问题变得更糟。
总而言之,您可能需要执行太多和/或太慢的finalize()
方法。可能是在一个问题环境中,finalize方法更慢?或者你有更多的处理能力,所以你在那里更快地创造垃圾?
我过去遇到过这个问题。为了减轻它,我提高了终结器线程的优先级。这样做的诀窍是在初始化期间创建一块垃圾,覆盖finalize()
并在完成期间更改当前线程中的线程优先级。在这种情况下,更改终结器线程的优先级足以解决问题,但不能保证能够解决问题。