10

8 つのコア (4 つの物理、4 つの HT) を持つ Core i7 ラップトップで Java プログラムを実行しています。プログラムは 8 つの並列スレッドを使用するため、すべての CPU を使用する必要があります。「-server」パラメーターを指定して実行すると、常に 100% になります。それがなければ、全体で約 50% から 60% です (常に 100% のピークと 30% のディップで変化します)。私が奇妙なことに気付いたのは次のとおりです。プログラムをデバッグで実行し、CPU 使用率が特に低い (30%) まで待ってから、実行を一時停止して 8 つのスレッドが何をしているかを調べたところ、ブロック状態になっているスレッドはありませんでした。 . さらに、それらの間の同期はほとんどありません。これが私が疑問に思っていることです:

  1. CPU がクライアントで 100% に達するのを妨げるサーバー VM とクライアント VM の違いは何ですか?
  2. 同期がない場合、スレッドがコアを完全に使い果たすのを妨げているのは何でしょうか? (おそらく1にリンクされています)

編集: ここに考えがあります: コードは大きな配列を割り当て、GC にかなり迅速に任せます。「newSomethingBig()」を呼び出してそのメモリの割り当てに時間がかかると、スレッドはスリープしますか? VM に一連のスレッドの割り当てを処理する単一のプロセスがある場合、同期ブロックの外でランダムに一時停止しているように見える理由を説明できると思います...

Edit2:GCが原因であると確信しています。VM にデフォルトの 500Mb の代わりに 1500Mb を与えると、CPU は再び 100% に達します。デフォルトでより多くのメモリを使用するため、サーバーモードではスローダウンは発生しないと思います。

4

2 に答える 2

3

特にJavaとは関係ありませんが、スレッドの数は、CPUを最大限に活用するために必要なコアの数よりも多くする必要があります。これは、特定のスレッドが実行できない場合が多く、別のスレッドによって保持されている条件変数を待機していることがより明白です。キャッシュミスがスレッドに待機を要求する可能性があるなど、他の理由でスレッドがブロックされる可能性があります。データがCPUキャッシュにロードされると、ソースからの入力を待機する必要があります。 CPUよりも遅いため、事実上メモリページングによりスレッドが待機する可能性があります。コアよりも多くのスレッドを使用することで、何らかの理由で1つのスレッドがブロックされた場合、別のスレッドが解放されたコアを利用できます。適切な初期値は、使用しているコアの数の約1.5倍です。

于 2013-02-15T13:20:22.140 に答える
2

Java スレッドが何をしているかを監視したい場合は、アプリケーションをデバッグ モードで実行したり中断したりしないでください。

むしろ、CPU 使用率が低下する特定の間隔でスレッド ダンプを収集する必要があります。kill -3 <pid>

2 番目の更新に関連して、タイムスタンプ付きの GC ロギングを有効にし、スローダウン/CPU 使用率の低下をヤング/フル GC コレクションの時間と関連付ける必要があります。

于 2013-02-16T05:35:12.573 に答える