1

サーバー側アプリケーションで、接続されたクライアントごとにソケット スレッドを開きます。各スレッドに DataInputStream があり、read(byte[]array) を呼び出してデータを読み取ります。また、ソケットのタイムアウトを数分に設定しました。主なコードは次のようなものです。

while (dataInputStream.read(array) != -1) { do something... }

ただし、数時間実行した後、jconsole で topthreads プラグインを使用すると、複数のクライアント スレッドがそれぞれ 20% 程度の CPU を使用していることがわかります。それをクリックすると、コール スタックはスレッドが上記の行の read() 関数でブロックされていることを示します。

read() 関数は通常、ブロックしてデータを待機することを知っています。ブロックされると、CPU サイクルをほとんど消費しません。今ではそれぞれ 20%ish を使用しており、同じ問題を抱えているスレッドが増えると、サーバーの実行速度がますます遅くなります。私のサーバーには 1 秒あたり約 5 件の接続要求がありますが、数時間で 5 つのスレッドだけに問題があるため、これはめったに発生しません。

私は本当に混乱しています。誰かが私を助けることができますか?

4

2 に答える 2

1

jvm がソケットからのデータの読み取りを待機している場合、システムが常に実行する必要のあるアクティビティがさらに多くなります。

私は正確なテクニックを使用していませんが、このリンクはいくつかのアイデアを与えるはずです..

BufferedInputStreamaまたはいずれかのsを使用してみませんかStreamReader..これらのクラスはパフォーマンスに役立ちます。

java.util.concurrent パッケージのクラスを使用して、スレッド処理を改善することもできます (スレッド プールを作成すると、消費されるメモリの合計を削減し、システム全体のパフォーマンスを向上させることができます)。これを既に行っているかどうかはわかりません。

于 2011-07-30T20:17:06.407 に答える
0
while (dataInputStream.read(array) != -1) { do something... }

とにかく、このコードは間違っています。返されたバイト数がわかるように、 read() の戻り値を変数に格納する必要があります。いずれにせよ、これがなければアプリケーションの残りの部分が確実に動作することはあり得ないため、この段階でタイミングを心配するのは時期尚早です。

ただし、アレイが非常に小さい場合を除き、実際にここで 20% の CPU を使用しているとは思えません。おそらく、経過時間の 20% がここで費やされます。ネットワーク読み取りのブロックは、CPU を使用しません。

于 2011-07-31T06:02:51.137 に答える