Javaアプリケーション(Webベース)があり、数時間にわたって非常に高いCPU使用率(ほぼ90%)を示すことがあります。LinuxTOP
コマンドはこれを示します。 、問題はなくなります。
調査するために:
スレッドダンプを使用して、スレッドが何をしているかを見つけます。いくつかのスレッドは'RUNNABLE'
状態で見つかり、いくつかは他のいくつかの状態で見つかります。繰り返されるスレッドダンプを取得すると、'RUNNABLE'
状態で常に存在するスレッドがいくつか表示されます。だから、彼らは犯人のようです。
しかし、どのスレッドがCPUを占有しているのか、無限ループに入っているのか(それによってCPU使用率が高くなる)を確実に判断することはできません。
問題のあるコードは何もログに記録していない可能性があるため、ログは必ずしも役に立ちません。
調査方法-アプリケーションまたはwhat-threadのどの部分が高いCPU使用率を引き起こしていますか?-その他のアイデアはありますか?
プロファイラーがセットアップに適用できない場合は、 この投稿 の手順に従ってスレッドを識別しようとする場合があります。
基本的に、3つのステップがあります。
top -H
およびCPUが最も高いスレッドのPIDを取得します。ガベージコレクションの問題の犠牲になる可能性があります。
アプリケーションがメモリを必要とし、ガベージコレクターを使用するように構成されているものが少なくなると、多くのCPUサイクルを消費するガベージコレクターが頻繁に実行されます。何も収集できない場合、メモリは少なくなり、繰り返し実行されます。アプリケーションを再デプロイすると、メモリがクリアされ、ガベージコレクションが必要以上に発生しないため、CPU使用率は再びいっぱいになるまで低くなります。
アプリケーションにメモリリークの可能性がなく、メモリ用に適切に構成されていることを確認する必要があります(-Xmx
パラメータ、 Javaオプション-Xmxの略称 )とは)
また、Webフレームワークとして何を使用していますか? JSFはセッションに大きく依存し、多くのメモリを消費します。ステートレスであることを考慮してください。
これらのピークCPU時間の間、ユーザーの負荷はどの程度ですか?これはWebベースのアプリケーションだと言うので、思い浮かぶのはメモリ使用率の問題です。たとえば、セッションに多くのものを保存し、セッションカウントが十分に高くなると、アプリサーバーはスラッシングを開始します。これは、使用しているスキームによってはGCが問題を悪化させる場合もあります。アプリとサーバー構成に関する詳細情報は、より多くのデバッグのアイデアを示すのに役立ちます。
スレッドダンプでは、次のように行番号を見つけることができます。
現在実行中のメインスレッド用...
"main" #1 prio=5 os_prio=0 tid=0x0000000002120800 nid=0x13f4 runnable [0x0000000001d9f000]
Java.lang.Thread.State: **RUNNABLE**
at Java.io.FileOutputStream.writeBytes(Native Method)
at Java.io.FileOutputStream.write(FileOutputStream.Java:313)
at com.rana.samples.**HighCPUUtilization.main(HighCPUUtilization.Java:17)**
最初のアプローチは、 Thread.sleep へのすべての参照を見つけて、それを確認することです。
睡眠は正しいことです-可能であれば、何らかの種類の待機メカニズムを使用する必要があります-おそらくBlockingQueue
を慎重に使用すると役立つでしょう。
睡眠が正しいことである場合、あなたは正しい時間眠っていますか?これはしばしば答えるのが非常に難しい質問です。
マルチスレッド設計で最もよくある間違いは、何かが起こるのを待つときにやらなければならないことは、それを確認し、短いループでしばらく寝ることだけだと信じることです。これが効果的な解決策となることはめったにありません。発生する場合は常にwait
を試みる必要があります。
2番目に一般的な問題は、スリープせずにループすることです。これはさらに悪く、追跡するのが少し簡単です。
質問に「linux」を割り当てませんでしたが、「Linux top」に言及しました。したがって、これは役に立つかもしれません:
小さなLinuxツールthreadcpuを使用して、スレッドを使用しているほとんどのCPUを特定します。 jstackを呼び出してスレッド名を取得します。また、パイプの「sort -n」を使用すると、CPUの使用順に並べられたスレッドのリストを取得できます。
詳細はこちらをご覧ください: http://www.tuxad.com/blog/archives/2018/10/01/threadcpu_-_show_cpu_usage_of_threads/index.html
さらに詳細が必要な場合は、スレッドダンプを作成するか、スレッドでstraceを実行します。