20

更新:これはメモリの問題のようです。3.8 Gb の Hprof ファイルは、この「ブロッキング」が発生したときに JVM がそのヒープをダンプしていたことを示していました。当社の運用チームは、サイトが応答していないことを確認し、スタック トレースを取得してからインスタンスをシャットダウンしました。ヒープダンプが完了する前にサイトをシャットダウンしたと思います。ログにはエラー/例外/問題の証拠はありませんでした。おそらく、エラー メッセージが生成される前に JVM が強制終了されたためです。

元の質問 最近、エンド ユーザーにはアプリケーションがハングするように見える状況がありました。アプリケーションを再起動する前にスタック トレースを取得したところ、驚くべき結果が得られました。527 スレッドのうち、463 スレッドの状態が BLOCKED でした。

過去 過去 に、ブロックされたスレッドには通常、次の問題がありました。2) ブロックされたスレッドはすべて、同じクラス/メソッド (jdbc またはファイル システム クラスなど) でブロックされます。

異常なデータ この場合、アプリケーション クラス (jdbc および lucene 呼び出しを含む) に加えて、jvm 内部クラス、jboss クラス、log4j などを含む、あらゆる種類のクラス/メソッドがブロックされていることがわかります。

JVM がlog4j.Hierarchy.getLogger 、java.lang.reflect.Constructor.newInstance をブロックする原因は何ですか? 明らかに「不足している」リソースもありますが、どのリソースですか?

ありがとう

意思

スタック トレースの抜粋

http-0.0.0.0-80-417" daemon prio=6 tid=0x000000000f6f1800 nid=0x1a00 waiting for monitor entry [0x000000002dd5d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at sun.reflect.GeneratedConstructorAccessor68.newInstance(Unknown Source)
                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
                at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
                at java.lang.Class.newInstance0(Class.java:355)
                at java.lang.Class.newInstance(Class.java:308)
                at org.jboss.ejb.Container.createBeanClassInstance(Container.java:630)

http-0.0.0.0-80-451" daemon prio=6 tid=0x000000000f184800 nid=0x14d4 waiting for monitor entry [0x000000003843d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at java.lang.Class.getDeclaredMethods0(Native Method)
                at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
                at java.lang.Class.getMethod0(Class.java:2670)

"http-0.0.0.0-80-449" daemon prio=6 tid=0x000000000f17d000 nid=0x2240 waiting for monitor entry [0x000000002fa5f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.register(Http11Protocol.java:638)
                - waiting to lock <0x00000007067515e8> (a org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler)
                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.createProcessor(Http11Protocol.java:630)


"http-0.0.0.0-80-439" daemon prio=6 tid=0x000000000f701800 nid=0x1ed8 waiting for monitor entry [0x000000002f35b000]
   java.lang.Thread.State: BLOCKED (on object monitor)
                at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:261)
                at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:242)
                at org.apache.log4j.LogManager.getLogger(LogManager.java:198)
4

1 に答える 1

20

これらは、収集された証拠に応じて、私が試す順序で大まかにリストされています。

  • GC の動作を見たことがありますか? メモリ不足ですか?その結果、newInstance()上記の他のいくつかがブロックされる可能性があります。で VM を実行し-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -verbose:gc、出力をログに記録します。障害/ロックアップの近くで過剰な GC 時間が発生していますか?
    • 状態は再現可能ですか? その場合は、JVM でさまざまなヒープ サイズを試して (-Xmx)、動作が大幅に変化するかどうかを確認してください。その場合は、メモリ リークを探すか、アプリのヒープのサイズを適切に調整してください。
    • 前の方法が難しく、必要なOutOfMemoryErrorときに調整できない場合は、GC チューナブルを調整できます... JDK6.0 XX オプションまたはJDK6.0 GC Tuning Whitepaperを参照してください。-XX:+UseGCOverheadLimit-XX:+GCTimeLimitおよび 関連するオプションを具体的に見てください。(これらは十分に文書化されていませんが、役立つかもしれないことに注意してください...)
  • デッドロックが発生する可能性がありますか? スタック トレースの抜粋だけでは、ここでは判断できません。スレッドがブロックされているモニター状態 (スレッドが保持しているものに対して) のサイクルを探します。私はあなたのためにこれを行うことができると信じてjconsoleいます...(はい、スレッドタブの下で、「デッドロックの検出」
  • いくつかの繰り返しスタックトレースを実行してみて、変更されたものと変わらないものを探してください...
  • フォレンジックを行います...「BLOCKED」と表示されているスタックエントリごとに、特定のコード行を調べて、そこにモニターがあるかどうかを調べます。実際のモニター獲得があれば、制限リソースを特定するのはかなり簡単です。ただし、一部のスレッドは、透過的に利用可能なモニターなしでブロックされているように見える場合があります。これらはよりトリッキーになります...
于 2010-10-25T16:32:31.290 に答える