インデックス

デッドロックとは

複数のスレッドがリソースをロックしているときに、全てのスレッドが無制限に待ち状態になり、 これをデッドロックと呼びます。

一番シンプルな例ですと、スレッドAがオブジェクトAをロックしている状態で、 オブジェクトBのロックを試みるケースのときに、 その間、他のスレッドBがオブジェクトBをロックした状態で オブジェクトAをロックしようと待機しているケースです。 このケースでは、スレッドAは、オブジェクトB待ちのため、オブジェクトAを決して開放することはありません。 同時に、スレッドBは、オブジェクトAが有効になるのを待っているため、 オブジェクトBをエンドレスで永久にロックしたままになるため、両者とも決して前に進めるはずがありません。

wrapper.check.deadlock プロパティ

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

注意

スレッドのデッドロックチェックには、Java バージョン 1.5 以上が必要です。 それより古い JVM ではチェックが無視されます。 Java バージョン 1.5 以上で(synchronized を利用して) スレッドロックをベースにした「モニター」に関わるデッドロックを検知することは可能です。 Java バージョン 1.6 以上で(ReentrantLock を利用して) 「owned」や「reentrant」スレッドロックに関わるデッドロックの検知も可能です。

Java 9 で、カスタムランタイムイメージjava.management モジュールを含まない場合、デッドロックチェックが無効になります。

この[wrapper.check.deadlock]プロパティは、他のプロパティとの組み合わせで、

デッドロックしたスレッドについて JVM をモニタリング(監視)するように Wrapper を設定します。 これは、難しい潜在的な重要問題の回避策として他に対策がない場合にでも、問題の検知にとても役に立ちます。

デッドロックのチェック処理は、わりと高速ですが、 全てのスレッドを一時的にロックしてスナップショットをとりますので、 このプロパティのデフォルト値は「FALSE」になっています。

設定例:(デッドロックチェック:OFF)
wrapper.check.deadlock=FALSE

シンプルな設定例:

各プロパティの詳細について下記をご覧ください。 次のシンプルな例では、デッドロック検知機能を有効にし、60 秒毎にチェックして、 デッドロックの発生場所など詳細ログを記録して、即座に JVM を再起動します。

設定例:
wrapper.check.deadlock=TRUE
wrapper.check.deadlock.interval=60
wrapper.check.deadlock.action=RESTART
wrapper.check.deadlock.output=FULL

wrapper.check.deadlock.interval プロパティ

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

この[wrapper.check.deadlock.interval]プロパティでは、 Wrapper がアプリケーションのデッドロックを検査するインターバル(一定間隔)を設定します。 最短で1秒毎に1回のインターバルを設定でき、デフォルト値は「60秒」(1分あたり1回)です。 一般的に、状態が安定していると分かっているアプリケーションの場合には、 このデッドロックチェックの頻度を大幅に開けることも良いでしょう。

設定例:(60秒毎に1回)
wrapper.check.deadlock.interval=60

wrapper.check.deadlock.action プロパティ

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

この[wrapper.check.deadlock.action]プロパティでは、 デッドロックを検知したときの Wrapper が行う動作について設定します。 デフォルトの動作では、 [RESTART] です。

設定例:
wrapper.check.deadlock.action=RESTART

可能なアクションは次のとおりです。

  • [DEBUG] :

    デバッグメッセージをログに記録します。 これは、アクションがいつ発生されるかを理解するのに役立ちます。

  • [STATS] (ver. 3.5.52から)(スタンダード版、プロフェッショナル版):

    パフォーマンス統計を出力します。

  • [DUMP] :

    スレッドダンプを生成します。

  • [GC] (ver. 3.5.7から):

    JVM で完全なガガベージコレクションスイープを実行します。 フルスイープを行うと、すべてのスレッドがフリーズすることが多いため、これを頻繁に行うと、JVM のパフォーマンスに影響を与えることに注意してください。

  • [RESTART] :

    現在の JVM を停止して、新しい「起動の試み(invocation)」として再起動します。

  • [SHUTDOWN] :

    Wrapper 同様に、JVM を終了します。

  • [USER_<n>] (プロフェッショナル版):

    ユーザー定義イベントを発生させます。 イベントには、「メール送信」か、 「外部システムコマンドの実行」か、 どちらかのアクションが可能です。 そのコマンド指定には、クリーンアップ作業や SNMP トラップを起こしたり、何でも可能です。

  • [PAUSE] :

    一時停止が可能で JVM が動作している場合、Java アプリケーションを一時停止します。 詳しくは[wrapper.pausable]プロパティをご覧ください。

  • [RESUME] :

    JVM が一時停止状態にあるとき、Java アプリケーションを再開します。 これは、JVM が停止ではなく一時停止している場合に利用可能です。 詳しくは[wrapper.pausable]プロパティをご覧ください。

  • [SUSPEND_TIMEOUTS_<n>] (ver. 3.5.40 から)(スタンダード版、プロフェッショナル版):

    JVM が応答しない場合、Wrapper に全てのタイムアウトを停止するように指示します。 「<n>」は、タイムアウトを停止する期間(秒数)を指定し、1-3600 (1秒から1時間まで)の範囲で設定できます。 これは、Java アプリケーションが長いブロックタスクを実行する必要がある時に Wrapper がアプリケーションが応答不能と判断するのを防ぐために使用できます。

    その他のアクションプロパティ、コマンドファイル、或いは Java WrapperManager.suspendTimeouts() メソッドでタイムアウトを停止することができます。

    タイムアウトを停止するリクエストが複数ある場合、各リクエストで指定されている秒数は加算されません。 代わりに、新しく指定された秒数が残りの停止期間より長い場合、停止期間が置き換えられますが、 それより短い場合は無視されます。

  • [RESUME_TIMEOUTS] (ver. 3.5.40 から)(スタンダード版、プロフェッショナル版):

    Wrapper に、停止された全てのタイムアウトを再開するように指示します。

    その他のアクションプロパティ、コマンドファイル、或いは Java WrapperManager.resumeTimeouts() メソッドでタイムアウトを再開することができます。

  • [SUCCESS] (ver. 3.5.5 から):

    起動失敗の内部カウントをリセットして、 現在のJVM 起動が成功したものとしてカウントします。 これはおそらくあまり役に立ちませんが、他のプロパティとの一慣性のために用意しました。

  • [NONE] :

    デッドロック検知の事実をログ化しますが、実際には何のアクションも起こしません。

注意

JVM を再起動しないようなアクション、例えば[NONE]アクションは、 デッドロックチェックが行われるたびに繰り返し発生しますので、ご注意ください。

複数のアクションを指定する:

スペースやカンマで区切ることで、複数のアクションを指定することが可能です。 複数のアクションを指定すると、迅速に指定した順番で続けて実行されます。

次の例では、スレッドダンプを実行して、その後、JVM を再起動します。

設定例:
wrapper.check.deadlock.action=DUMP,RESTART

wrapper.check.deadlock.output プロパティ

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

この[wrapper.check.deadlock.output]プロパティでは、 デッドロックを検知したとき、Wrapper がログ化する情報レベルを設定します。 デフォルト出力では、 [FULL] (完全なフルログ)です。

設定例:
wrapper.check.deadlock.output=FULL

可能な出力レベルは次のとおりです。

  • [FULL] :

    JVM 内部で[WrapperManager]クラスが、 デッドロックで呼び出されたスレッドの完全な スタックトレースを含むレポートを出力します。

    「FULL」(フル)の出力例:
    INFO   | jvm 1    | WrapperManager エラー: 2個のデッドロックのスレッド見つかりました!
    INFO   | jvm 1    | WrapperManager エラー: =============================
    INFO   | jvm 1    | WrapperManager エラー: "Locker-2" tid=18
    INFO   | jvm 1    | WrapperManager エラー:   java.lang.Thread.State: BLOCKED
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock.lockSecond(DeadLock.java:64)
    INFO   | jvm 1    | WrapperManager エラー:       - 応答待機中: <0x000000002fcac6db> (a java.lang.Object) 所有元: "Locker-1" tid=17
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock.lockFirst(DeadLock.java:83)
    INFO   | jvm 1    | WrapperManager エラー:       - ロック済み <0x0000000029c56c60> (a java.lang.Object)
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock.access$100(DeadLock.java:22)
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock$1.run(DeadLock.java:42)
    INFO   | jvm 1    | WrapperManager エラー:
    INFO   | jvm 1    | WrapperManager エラー: "Locker-1" tid=17
    INFO   | jvm 1    | WrapperManager エラー:   java.lang.Thread.State: BLOCKED
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock.lockSecond(DeadLock.java:64)
    INFO   | jvm 1    | WrapperManager エラー:       - 応答待機中: <0x0000000029c56c60> (a java.lang.Object) 所有元: "Locker-2" tid=18
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock.lockFirst(DeadLock.java:83)
    INFO   | jvm 1    | WrapperManager エラー:       - ロック済み <0x000000002fcac6db> (a java.lang.Object)
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock.access$100(DeadLock.java:22)
    INFO   | jvm 1    | WrapperManager エラー:     場所: org.tanukisoftware.wrapper.test.DeadLock$1.run(DeadLock.java:42)
    INFO   | jvm 1    | WrapperManager エラー:
    INFO   | jvm 1    | WrapperManager エラー: =============================
    STATUS | wrapper  | スレッドデッドロックを検知しました。 JVM再起動中。
    
  • [SIMPLE] :

    JVM 内部で[WrapperManager]クラスが、 デッドロックで呼び出されたスレッドやオブジェクトの簡単な概要だけを含むレポートを出力します。 多くの場合、特によく知られた問題に関しては十分です。

    「SIMPLE」(シンプル)の出力例:
    INFO   | jvm 1    | WrapperManager エラー: 2個のデッドロックのスレッド見つかりました!
    INFO   | jvm 1    | WrapperManager エラー: =============================
    INFO   | jvm 1    | WrapperManager エラー: "Locker-2" BLOCKED 応答待機中: java.lang.Object 所有元: "Locker-1"
    INFO   | jvm 1    | WrapperManager エラー: "Locker-1" BLOCKED 応答待機中: java.lang.Object 所有元: "Locker-2"
    INFO   | jvm 1    | WrapperManager エラー: =============================
    STATUS | wrapper  | スレッドデッドロックを検知しました。 JVM再起動中。
    
  • [NONE] (ver. 3.5.16 から):

    JVM 内部で[WrapperManager]クラスが、全ての出力を抑えます。 これはシステム製品の利用に向いています。 問題は把握しており、「たくさんのログ情報を望まない」、あるいは「保持する必要がない」ケースに適しています。 その他の選択として、Wrapper プロセスは、 トリガーされたアクションが発生した理由を提供するために、 常に一行のエントリをログ化します。

    「NONE」の出力例:
    STATUS | wrapper  | A Thread Deadlock was detected in the JVM.  Restarting JVM.