0

本番環境でjvmがハングした問題の1つをトラブルシューティングしているときに、次のロガーステートメントを実行するスレッドの1つに遭遇しました。

logger.debug("Loaded ids as " + ids + ".");

このステップで、スレッドステータスが実行可能としてハングします。ここでidsはセットです。カウントダウンラッチを介して上記のスレッドを待機し、タスクを完了する別のスレッドがあります。ソフトウェアは15分ごとにスレッドダンプを取得し、2つのスレッドのスタックトレースは次のようになります

Stack trace for [THREAD GROUP: Job_Executor] [THREAD NAME:main-Runner Thread][THREAD STATE: WAITING]
    ...sun.misc.Unsafe.park(Native Method)
    ...java.util.concurrent.locks.LockSupport.park(Unknown Source)
    ...java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
    ...java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
    ...java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
    ...java.util.concurrent.CountDownLatch.await(Unknown Source)
    ...com.runner.MainRunner.stopThread(MainRunnerRunner.java:1334)


Stack trace for [THREAD GROUP: Job_Executor] [THREAD NAME:task executor][THREAD STATE: RUNNABLE]    
    ...java.util.AbstractCollection.toString(Unknown Source)           
    ...java.lang.String.valueOf(Unknown Source)      
    ...java.lang.StringBuilder.append(Unknown Source)    
    ...com.runner.CriticalTaskExecutor.loadByIds(CriticalTaskExecutor.java:143)

このjvmはほぼ24時間ハングし、最終的に先に進むためにそれを強制終了する必要がありました。スレッドダンプは、上記を含めてRUNNABLE状態のスレッドが43個あることを示しています。

collection.toString()を実行するだけで、上記のスレッドが24時間RUNNABLE状態になる理由は何でしょうか。

続行する方法について何か提案はありますか?

4

2 に答える 2

1

collection.toString() を実行するだけで、上記のスレッドが 24 時間 RUNNABLE 状態になる理由は何でしょうか?

問題を診断するのに十分な情報が提供されていません。ここで JVM の問題が発生していると思い込まないようにお願いしたいだけです。

メソッドのソースAbstractCollection.toString()を見ると、コレクションを反復処理し、およそ "[ item0, item1, item2 ]" を出力していることがわかります。各item.toString()メソッドは、アイテムを表示するために呼び出されます。

アプリケーションのハングがコレクション内にある場合、コレクションtoString()の反復子に問題があると思います。これは、アプリケーションが回転している場合 (CPU を 100% 近く使用している場合) にわかります。たぶん、のhasNext()メソッドSetは常に返されていtrueますか?

アプリケーションのハングが実際に の内部にある場合はitem.toString()、アイテムが単純なフィールドを表示しているだけであることを確認します。遅延ロードされた ORM でラップされたフィールドのように、アクセスされた場合に RPC 呼び出しを行うフィールドには注意してください。

Set問題の詳細を提供し、id.toString()コードを提示していただければ、さらにサポートいたします。

これは一連のIntegerオブジェクトのように聞こえます。これによりアプリケーションがハングする理由がわかりません。他のいくつかのアイデアを次に示します。

  • このコレクションに非同期でアクセスしていませんか? 複数のスレッドがコレクションに変更を加えたためにコレクションが破損し、イテレータがスピンした可能性はありますか? でラップしてみてくださいCollections.synchronizedSet(...)
  • Set巨大で、メモリ不足に近づいていて、プログラムがスラッシングしている可能性はありますか? ただし、それによってアプリケーションがハングすることはありませんが、クロールが遅くなるだけです。そして、メモリ不足の例外が発生し始めます。
  • toString()が何度も呼び出されている可能性はありますか? ただし、ログに表示されると思います。
于 2012-10-09T13:58:51.797 に答える