7

私たちのサーバーでは、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たが、成功せず、OutOfMemoryErrors の頻度のみが減少したため、最初はそれが役立つと考えました.

最後に、JVM のバグを疑い、OpenJDK 1.6.0_30 から Oracle JDK 1.7.0_51 にアップグレードしたところ、問題はなくなりました (少なくともそう思われます。過去 4 時間、使用されたヒープは増加しませんでした)。finalize メソッドの変更も、ライブラリのアップグレードも行っていません。その間、小さな開発が行われただけです。この問題は、本番サーバーが 32 ビットであるのに対し、64 ビット JVM であることを除いて同じ構成のテスト サーバーでは再現しません。

問題は、オブジェクトがファイナライズされず、Finalizerスレッドが次のオブジェクトを待機している原因は何でしょうか? ヒープダンプを正しく分析しましたか?

すべての回答に感謝します。

4

2 に答える 2

1

OpenJDK バージョン 1.6.0_30 に関連していると考えられます。Oracle JDK 1.7.0_51 にアップグレードすると、問題はなくなりました。また、openJDK の自動更新後に発生したと思われますが、こちらも確認できておりません。関連するバグ レポートは見つかりませんでした。

于 2014-03-18T13:14:02.330 に答える