私たちのサーバーでは、OutOfMemoryError
. Eclipse メモリ分析を使用してヒープ ダンプを分析したところ、多くのオブジェクトがファイナライズのために保持されていることがわかりました (ヒープの約 2/3)。
finalize() メソッドのブロッキングである可能性があることがわかりました。この問題に関するいくつかのバグ レポート (ここまたはここ) を見つけましたが、常にファイナライザー スレッド スタックに現れ、どこかでブロックされていました。しかし、私たちの場合、このスレッドは待機していました:
"Finalizer" daemon prio=10 tid=0x43e1e000 nid=0x3ff in Object.wait() [0x43dfe000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
- locked <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
編集:
次に、 を追加しようとしまし-XX:+UseConcMarkSweepGC
たが、成功せず、OutOfMemoryError
s の頻度のみが減少したため、最初はそれが役立つと考えました.
最後に、JVM のバグを疑い、OpenJDK 1.6.0_30 から Oracle JDK 1.7.0_51 にアップグレードしたところ、問題はなくなりました (少なくともそう思われます。過去 4 時間、使用されたヒープは増加しませんでした)。finalize メソッドの変更も、ライブラリのアップグレードも行っていません。その間、小さな開発が行われただけです。この問題は、本番サーバーが 32 ビットであるのに対し、64 ビット JVM であることを除いて同じ構成のテスト サーバーでは再現しません。
問題は、オブジェクトがファイナライズされず、Finalizer
スレッドが次のオブジェクトを待機している原因は何でしょうか? ヒープダンプを正しく分析しましたか?
すべての回答に感謝します。