2014-10-17 23 views
0

我的應用程序在兩種環境中工作正常,但在驗收測試環境中存在內存泄漏。 JVM堆轉儲顯示堆滿98%java.object.finalize()(如果我沒有記錯的話,GC日誌聲明GC正在越來越頻繁地執行Full GC,直到JVM發出內存不足 - 錯誤。java堆滿Java finalize()調用

這可能是什麼原因造成的?應用程序在所有環境中都是一樣的,但操作系統和網絡在問題環境中略有不同,Java在所有環境中都是一樣的。 Object Finalize(),但由於某種原因它沒有完成?我正在使用JBoss EAP 5.

+0

嘗試使用jProfiler,它是一個非常棒的工具來查找泄漏,您將能夠找到導致此問題的類。 – 2014-10-17 13:28:38

+2

你是否爲任何對象重寫了'finalize()'? – 2014-10-17 13:28:41

+0

我們還沒有重寫finalize()在任何地方 – user1340582 2014-10-21 05:30:35

回答

1

有可能創建垃圾,要求終止速度比它能夠最終化的速度快當一個對象被確定爲無法訪問時,符合收集條件)並且要求完成,它將被添加到終結器隊列中而不是立即收集。在完成終結器後的下一個GC中,可以收集對象。換句話說,最終化會延遲內存的恢復。

有一個執行所有finalize方法的線程,默認情況下它的運行優先級與所有其他線程相同。如果你有很多創建垃圾的線程需要完成,他們可以比一個終結器線程能夠執行finalize()方法更快地產生垃圾。另外,如果你最終確定的方法不是很快,你只會讓這個問題變得更糟。

總之,您可能有太多和/或太慢的方法來執行。這可能是因爲在一個問題環境中,敲定方法較慢?或者你有更多的處理能力,所以你更快地創建垃圾?

我已經遇到過這個問題。爲了緩解它,我提高了終結器線程的優先級。這樣做的訣竅是在初始化過程中創建一段垃圾,它會覆蓋finalize()並在最終確定期間更改當前線程中的線程優先級。在這種情況下更改終結器線程的優先級足以解決問題,但不能保證執行該技巧。

+0

嗯聽起來像一個黑客? :)問題環境比沒有問題的環境更強大。我們也不會重寫finalize。 – user1340582 2014-10-21 06:31:38

+0

我的解決方法絕對是一種破解。根本原因是JVM中的設計錯誤。這個bug往往只會在更強大的環境中體現出來,因爲JVM最終確定的能力並沒有隨着核心的添加而擴展,但是應用程序創建垃圾的能力往往隨着核心的添加而線性擴展。 – Rob 2014-10-21 15:59:56