2012-07-05 20 views
9

TomcatでJava EEベースのアプリケーションを実行していて、数時間実行した後にアプリケーションが突然停止することがあります。 Javaプロセスのスレッドダンプの分析

は、私はそれがハングアップする直前にアプリケーションからのスレッドダンプを収集し、分析のためにTDAにそれを置く:

enter image description here

TDA(スレッドアナライザをダンプ)上記のモニターのための次のようなメッセージを与える:

A lot of threads are waiting for this monitor to become available again. 
This might indicate a congestion. You also should analyze other locks 
blocked by threads waiting for this monitor as there might be much more 
threads waiting for it. 

そして、ここでは、スレッドのスタックトレースは、上記の強調表示されています:

"MY_THREAD" prio=10 tid=0x00007f97f1918800 nid=0x776a 
      waiting for monitor entry [0x00007f9819560000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at java.util.Hashtable.get(Hashtable.java:356) 
    - locked <0x0000000680038b68> (a java.util.Properties) 
    at java.util.Properties.getProperty(Properties.java:951) 
    at java.lang.System.getProperty(System.java:709) 
    at com.MyClass.myMethod(MyClass.java:344) 

"waiting for monitor entry"状態の意味を知りたいですか?また、この問題をデバッグするための参考になる点もありがとうございます。

+4

Iこれを繰り返して呼び出すのではなく、システムプロパティのルックアップをキャッシュします。あなたは、アプリケーションの寿命の間に約12倍以上System.getProperty()を呼び出す必要はありません。つまり、ボトルネックではなくコード化する必要があります。 –

+0

ねえ。いいポイントピーター! – peakit

答えて

1

Monitor = synchronized。あなたは、同じオブジェクトにロックを取得しようとするスレッドがたくさんあります。

たぶん、あなたはこれがあなたのスレッドは(Hashtableの上の)ロックを設定しようとしているが、いくつかの他のスレッドがすでにそれをアクセスしているし、ロックを設定したことを意味ハッシュテーブルを使用してから切り替えてHashMapの

+0

「Hashtable」を直接使用していないことがわかりましたら、それは私の 'System.getProperty()'呼び出しから来ています。 'System.getProperty()'のノンブロッキング版はありますか?ありがとう! – peakit

1

を使用する必要があります。ロックが解除されるのを待っています。あなたの他のスレッドが何をしているかを確認してください。特にtid = "0x00007f9819560000"のスレッド

+0

興味深いことに、スレッドダンプファイルに 'tid = 0x00007f9819560000'のスレッドはありません。何か案が? – peakit

+0

Mmmmh、おそらくVMモニタテーブルロックです。コードを見るのが短く、厳しいものになるでしょう。基本的に、ハッシュテーブルは2つのスレッド間で競合しています。 1つのオプションは、HashtableをHashMapに置き換えることです(HashMapはスレッドセーフではないためです)。私はあなたがプロパティを使用していることを知っているだけでマップにコピーし、後でマップを使用します。したがって、競合(ConcurrentModificationExceptionおそらく)でそれが爆発するのを見るか、ロックが必要でないために作業を開始します。 – mprivat

5

あなたのスレッドのうちの1つがモニタオブジェクト(オブジェクトに対する排他ロック)を取得しました。これは、スレッドが同期コードを実行していることを意味し、何らかの理由でそこに停滞し、おそらく他のスレッドを待っています。しかし、他のスレッドは同期ブロックに遭遇し、ロック(モニタオブジェクト)を要求したため実行を続行できませんが、他のスレッドから解放されるまで取得できません。だからおそらくデッドロック。

2

してください全スレッドダンプからこの文字列を

を見て - あなたはそれを見つけることができれば< 0x00007f9819560000>

をロックし、スレッドがスレッドでデッドロックである "TID = 0x00007f97f1918800"

+0

はいbobon、この文字列のスレッドダンプ全体を検索しましたが、質問で強調表示されているスレッドとは別に、このIDの他の参照を見つけることができませんでした。 – peakit

関連する問題