4

ほとんどの場合、CPU を 100% 消費している Java アプリケーションがあります (cacti と top の監視で示されています)。YourKit を起動すると (CPU リソースの問題が確認されます)、15% の時間で java.net.SocketInputStream.read(byte[], int, int) が最大のホット スポットとして識別されます。SocketInputStream.read のようにブロッキング IO を実行するメソッドの CPU 時間を正確に測定していないと思います。

他に 6 つの特定されたホット スポットがありますが、それらを合わせた CPU 時間の 20% 未満しか占めていません。すべて 5%-1% の範囲です。

だから私は問題があることを知っています、私は問題を見ることができます、あなたのキットもそうですが、私は実際の問題を特定することに近づいていません.

私はプロファイラーを使用するのにかなり慣れていないため、何かが欠けている可能性があります。何か案は?

編集: Sean は、システムに組み込まれたツールの使用について良い点を指摘しています。top と shift+h を使用してスレッドを表示すると、7 ~ 15 のスレッドが表示され、CPU 使用率が跳ね上がります。問題を引き起こしているのは 1 つのスレッドではなく、各スレッドがある時点で実行されるコードの一部であるとは考えていません。

4

5 に答える 5

3

可能であれば、これを Solaris ボックスで実行することをお勧めします。Solaris ボックスがない場合は、Open Solaris を実行する仮想マシンをセットアップすることを検討してください。

Solaris はprstatというツールを提供しています

Prstat は、ほとんどの人がよく知っている top と同じように機能します。重要な違いは、prstat がプロセスを分割し、プロセス内の各スレッドを表示できることです。

あなたの場合、使用法は prstat -L 0 1 になります

スレッド ダンプ (スクリプトでこれを行うことをお勧めします) と組み合わせると、LWPID を照合して、CPU を占有しているスレッドを正確に見つけることができます。

これが機能的な例です(私は poc のために大きなループに入る小さなアプリを作成しました)

Standard Top は次のようなものを表示します

 PID USERNAME NLWP PRI NICE  SIZE   RES STATE    TIME    CPU COMMAND
  924 username   10  59    0   31M   11M run      0:53 36.02% java

次にprstatを使用して次のコマンドを使用しました

 prstat -L 0 1 | grep java > /export/home/username/Desktop/output.txt

そしてprstatからの出力

PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/LWPID    
924 username   31M   10M run     30    0   0:00:09  35% java/10
924 username   31M   10M sleep   59    0   0:00:00 0.8% java/3
924 username   31M   10M sleep   59    0   0:00:00 0.6% java/2
924 username   31M   10M sleep   59    0   0:00:00 0.3% java/1

これは上とあまり変わらないように見えるかもしれませんが、データの右側を見ると、PROCESS/LWPID は、CPU を消費している Java プロセス内の正確なスレッドを示しています。軽量プロセス ID (lwpid) 10 で実行されているスレッドは、CPU の 35% を消費しています。前述したように、これをスレッド ダンプと組み合わせると、正確なスレッドを見つけることができます。私の場合、これはスレッド ダンプの関連部分です。

"Thread-0" prio=3 tid=0x08173800 nid=0xa runnable [0xc60fc000..0xc60fcae0]
   java.lang.Thread.State: RUNNABLE
    at java.util.Random.next(Random.java:139)
    at java.util.Random.nextInt(Random.java:189)
    at ConsumerThread.run(ConsumerThread.java:13)

スレッドの一番上の行で、nidを LWPID に一致させることができます。nid=0xa (16進数から10進数に換算すると10)

prstat コマンドとスレッド ダンプ コマンドをスクリプトに入れ、CPU 使用率が高いときに 4 ~ 5 回実行すると、パターンが見え始め、CPU 使用率が高い原因を特定できるようになります。

私はこれまで、gc の実行時間が長く、LDAP 接続の構成ミスが原因であることに気づきました。楽しむ :)

于 2011-07-29T04:46:34.850 に答える
2

あなたは均一に遅いコードを持っているかもしれませんか?

于 2011-07-29T03:13:24.553 に答える
1

jvisualvmプロファイラーは、比較のための便利な代替手段です。JDK に含まれています。

于 2011-07-29T03:08:46.083 に答える
1

メモリ トレースと CPU プロファイリングをオンにして、CPU プロファイラをもう一度確認します。これにより、最適化するさまざまな領域が表示されます。

CPU を 100% 使用していると言う場合、それがユーザーまたはシステム/カーネル空間にあるかどうかを確認できます。例えばトップ。プロファイラーは、カーネル空間で使用されている CPU を表示しません。

スレッドはいくつありますか?アイドル スレッドが十分にある場合は、スレッド間を切り替えるだけで 100% 以上の CPU を使用できます。(何千も持つ必要があります)

同様の回答と同様に、ソケットの読み取り、スレッド間のスワップ、GC の実行など、実際の作業をあまり行っていないアプリケーションのオーバーヘッドが非常に多い可能性が非常に高いです。プロファイラーは、オーバーヘッドを拾うのが得意ではありません。

于 2011-07-29T06:40:29.263 に答える
0

1 つの可能性は、JVM に十分なメモリがないため、常に GC を実行していることです。

于 2011-07-29T03:40:22.753 に答える