一回のデバッグの過程を覚えます:windowsの下でjavaアプリケーションのCPUとメモリを探して高すぎます
最近1つのマルチスレッドプログラムを書いて、同時量のピークは5,6千、甚だしきに至っては8,9千のスレッドがあります.いくつかのデバッグを経て、プログラムはやっと正常に運行することができて、実際には“正常に運行します”の背後は“隠れている玄機”です.プログラムを4、5時間実行すると、コンピュータのシャーシが非常に暑く、ファンの回転が非常に速いことがわかります.タスクマネージャを開くと、プログラムのCPUが90%前後に暴走し、メモリが4 G程度消費されていることがわかります.プログラムは正常に見えますが、logファイルをチェックすると問題があり、データが非常に失われています.
CPUがいっぱいになり、スレッドが切り替わらないためにデータが失われたのではないかと推測します.では、なぜCPUがいっぱいになるのでしょうか.ネットで無数の資料を調べた後、私のバグ探しの道のりを始めました.
1、タスクマネージャまたは
cmdコンソールで
2、jstackコマンドでプロセスのすべての情報をリストする
コマンド
3、pslistツールを使用してプロセスのすべてのスレッドの詳細を表示する
cmdコンソールでpslistを入力します.コマンドが認識されない場合は、現在のコンピュータにpslistというツールがインストールされていないことを示します.windowsの公式サイトにアクセスできます.https://technet.microsoft.com/en-us/sysinternals/bb896682.aspxダウンロード、ダウンロードが完了したら
インストールが完了したら、
出力されたファイルを開くと、次のように表示されます.
このファイルに記載されている情報から、最もリソースを消費するスレッドを見つけることができます.その後、そのTid(スレッドID)を16進数(windowsの下の計算機を直接利用すればよい)に変換し、
最後に、私は私のプログラムが最も資源を消費するスレッドがすべてのGCスレッドであることを発見しましたが、プログラムの中で私の作業スレッドは基本的にブロック状態にあります(以上のスクリーンショットは体現されていません.プロセス26028は正常な運行時に私がスクリーンショットした図です).ではなぜGCはこんなに資源を消費しているのでしょうか.最初はどのリソースが解放され忘れたのかと思っていたので、開いているバイトストリーム、socketリソースなどを一度閉じたことを確認しました.しかし、プログラムを再実行してから4、5時間後も同様の問題が発生した.明らかに問題は解決されていない.
4、jmap+MAT分析
MATツールのインストールと使用については、ネット上に多くの資料がありますが、ここでは説明しません.
プログラムを実行する、問題が発生した場合、jmapコマンドを使用してメモリdumpをファイルに、コマンドは
その後、MATツールを使用するdumpファイルであるjmapをロードする.bin、分析を行います.
最後に、データベース接続オブジェクトがメモリに蓄積されていることを発見しました.3 G近くのメモリを占めています.不思議なことに、このコードは多くのプログラムで多重化されていて、問題はありませんでした.だから私は高い同時性による問題であるべきだと判断して、データベースはこのような大きな圧力に耐えられないかもしれません.
私はデータベースに格納されたコードを先に注釈して、ファイルに格納した後、すべて正常になりました.
はい、バグは見つかりました.次に、高同時データベース設計を見に行きます.
次に、バグを調整する際に使用するツールをいくつか紹介します.
5、jconsoleとjvisualvmツール
どちらのツールもJDK独自のjavaプログラムを監視するツールで、ローカルプロセスとリモートプロセスを監視できます.jvisualvmが提供する情報はもっと多いです.cmdコンソールに
jvisualvmのインタフェースは次のとおりです.
6、windowsが提供するprocess explorerツール
このツールは、タスクマネージャよりも詳細なプロセス情報を提供し、各プロセスのスレッドを表示できるオンラインでダウンロードできます.
CPUがいっぱいになり、スレッドが切り替わらないためにデータが失われたのではないかと推測します.では、なぜCPUがいっぱいになるのでしょうか.ネットで無数の資料を調べた後、私のバグ探しの道のりを始めました.
1、タスクマネージャまたは
jps
命令を利用して私のプログラムのプロセスIDを見つけるcmdコンソールで
jps
コマンドを入力すると、現在のコンピュータで実行されているjavaプログラムのすべてのプロセスがリストされます.私のプログラムのプロセスIDは26028です.2、jstackコマンドでプロセスのすべての情報をリストする
コマンド
jstack 26028 > 26028.txt
を使用するプロセスID 26028のプロセス情報をリストし、26028に出力する.txtテキストファイルにあります.その後、このファイルを開くと、スレッドのステータス、スレッドのID番号、スタック情報など、現在のプロセスのすべてのスレッド情報が表示されます.ファイルの最後に、GCを担当するスレッドがいくつか見られます.nidはスレッドのIDです.3、pslistツールを使用してプロセスのすべてのスレッドの詳細を表示する
cmdコンソールでpslistを入力します.コマンドが認識されない場合は、現在のコンピュータにpslistというツールがインストールされていないことを示します.windowsの公式サイトにアクセスできます.https://technet.microsoft.com/en-us/sysinternals/bb896682.aspxダウンロード、ダウンロードが完了したら
C:\Windows\System32
のパスに解凍して使用するか、環境変数に設定してもよい.インストールが完了したら、
pslist -dmx 26028 > 26028_pslist.txt
コマンドを使用して、プロセスIDが26028のプロセスのすべてのスレッドの詳細(スレッドID、コンテキスト切り替え、ステータスなど)をリストできます.出力されたファイルを開くと、次のように表示されます.
このファイルに記載されている情報から、最もリソースを消費するスレッドを見つけることができます.その後、そのTid(スレッドID)を16進数(windowsの下の計算機を直接利用すればよい)に変換し、
jstack
コマンドで生成されたファイルを検索すると、具体的にどのスレッドが何をしているのか、なぜリソースを消費しているのかを調べることができます.最後に、私は私のプログラムが最も資源を消費するスレッドがすべてのGCスレッドであることを発見しましたが、プログラムの中で私の作業スレッドは基本的にブロック状態にあります(以上のスクリーンショットは体現されていません.プロセス26028は正常な運行時に私がスクリーンショットした図です).ではなぜGCはこんなに資源を消費しているのでしょうか.最初はどのリソースが解放され忘れたのかと思っていたので、開いているバイトストリーム、socketリソースなどを一度閉じたことを確認しました.しかし、プログラムを再実行してから4、5時間後も同様の問題が発生した.明らかに問題は解決されていない.
4、jmap+MAT分析
MATツールのインストールと使用については、ネット上に多くの資料がありますが、ここでは説明しません.
プログラムを実行する、問題が発生した場合、jmapコマンドを使用してメモリdumpをファイルに、コマンドは
jmap -dump:format=b,file=jmap.bin 26028
である.その後、MATツールを使用するdumpファイルであるjmapをロードする.bin、分析を行います.
最後に、データベース接続オブジェクトがメモリに蓄積されていることを発見しました.3 G近くのメモリを占めています.不思議なことに、このコードは多くのプログラムで多重化されていて、問題はありませんでした.だから私は高い同時性による問題であるべきだと判断して、データベースはこのような大きな圧力に耐えられないかもしれません.
私はデータベースに格納されたコードを先に注釈して、ファイルに格納した後、すべて正常になりました.
はい、バグは見つかりました.次に、高同時データベース設計を見に行きます.
次に、バグを調整する際に使用するツールをいくつか紹介します.
5、jconsoleとjvisualvmツール
どちらのツールもJDK独自のjavaプログラムを監視するツールで、ローカルプロセスとリモートプロセスを監視できます.jvisualvmが提供する情報はもっと多いです.cmdコンソールに
jconsole
とjvisualvm
を直接入力すると、この2つのツールを呼び出すことができます.jconsoleのインタフェースは次のとおりです.jvisualvmのインタフェースは次のとおりです.
6、windowsが提供するprocess explorerツール
このツールは、タスクマネージャよりも詳細なプロセス情報を提供し、各プロセスのスレッドを表示できるオンラインでダウンロードできます.