レポート A のデータ損失を発見し、プログラムの実行ログを見つけたところ、ログのごく一部 (通常は 12G) しかないことがわかりましたが、今日はわずか 243M でした。
ただし、レポート B では、プログラムの実行が完了していることがわかります。したがって、プログラムは実行されているものの、ログが欠落していると推測できます。
proc ファイル システムに基づいて関連情報を検索する
いくつかのログファイルが見つかりました
ファイルを開くと、それが確かに今日紛失したファイルであることがわかります。ファイルを末尾で実行すると、そのファイルを待機しているスレッドがあることがわかります。
説明ファイルのスレッドでデッドロックが発生しました。
Java メモリ分析コマンド (jstack 5669) を使用してメモリを分析すると、SocksSocketImpl サービスがロックされていることがわかります。
ログが失われる前に例外が発生した場所を確認してください。ソケットによって引き起こされる例外もあります。
したがって、この例外により別の子プロセスがデッドロック状態になるため、この例外を解決する必要があります。
メモリ内のオブジェクトで例外が発生しましたが、この例外が適切にキャプチャされなかったため、スレッドがデッドロック状態のままになっていることがわかります。
最後に、ソース コードを確認すると、待機している主な理由は、変数 liveMutThreadNum がアトミックな操作を実行していないことがわかりました。
以下に示すように: Suoran は、aliveMutThreadNum 変数を操作するときにロックを使用しますが、同期は依然として最も安全な形式ではありません。
1 synchronized は通常、クラス ロックを取得するために使用されます。
2 メソッドは同期されていますが、メソッドが適切な場所で使用されていない場合、結果は依然としてデッドロックになります。このデッドロックは、例外をキャッチする際に、aliveMutThreadNum が最終的に処理されず、該当メソッドが呼び出されたにもかかわらず、このステップまでプログラムが実行されなかったため、デッドロックが発生しました。
正しいアプローチは、変更に volatile キーワードを使用し、それを try catche Final の Final で処理することです。
さらに、 1. プログラム カウンタはこのように書かず、countdownlatch クラスを使用して処理するのが最善です。
2. デッドロックが発生した場合、ホットスワップを使用すると、デッドロック部分をスキップして他のプログラムの実行を継続するように Java に手動で命令できる必要があります。