質問

Java 1.6 x64 で多数のスレッドを待機状態にするとどれくらいのコストがかかるのか疑問に思っています。

より具体的には、多くのコンピューター間で実行され、あるコンピューターから別のコンピューターにデータを送受信するアプリケーションを作成しています。1) データの送信、2) データの受信、3) 接続が切断された場合の接続の再確立など、接続されているマシンとタスクごとに個別のスレッドを用意するほうが快適だと感じます。したがって、クラスター内に N 個のノードがあるとすると、各マシンは N-1 個の隣接ノードごとに 3 つのスレッドを持つことになります。通常は 12 台のマシンがあり、通信スレッドは 33 になります。

これらのスレッドのほとんどはほとんどの時間スリープ状態になるため、最適化の目的でスレッドの数を減らし、各スレッドにより多くのジョブを割り当てることができます。たとえば。接続の再確立は受信スレッドの責任です。または、接続されているすべてのマシンへの送信は単一スレッドで行われます。

では、多くのスリープ状態のスレッドがあると、パフォーマンスに重大な影響があるのでしょうか?

役に立ちましたか?

解決

ほとんどの場合、スリープ状態のスレッドによって消費されるリソースはそのスタック領域になります。接続あたり 2 スレッドのモデルを使用すると、これはあなたが説明していることと似ていると思いますが、接続数が大きくなると、まさにこの理由により、スケーラビリティに大きな問題が発生することが知られています。

私自身もこの状況に陥ったことがありますが、接続数が 500 接続 (約 1,000 スレッド) を超えると、スレッドのスタック スペースの使用量が最大量を超えるため、OutOfMemoryError が発生するケースが多くなる傾向があります。単一プロセスのメモリ。少なくとも私たちの場合は、32 ビット Windows 上の Java 環境でした。調整してさらに進めることはできると思いますが、最終的には大量のメモリを浪費するため、あまり拡張性がありません。

多数の接続が必要な場合は、Java NIO (新しい IO など) を使用すると、同じスレッドで多数の接続を処理できるようになります。

そうは言っても、ある程度最新のサーバーでは 100 スレッド未満であれば、たとえリソースの無駄遣いであっても、大きな問題は発生しないはずです。

他のヒント

NIO に切り替える前にも同じ問題がありました。そのため、私はそのフレームワークに従うというリードマンの推奨事項を 2 番目に支持します。チュートリアルを見つけることができるはずですが、詳細が必要な場合は、以下をお勧めします Java NIO ロン・ヒッチンズ著。

NIO に切り替えることで、処理できる接続数が大幅に増加しました。これは私たちにとって非常に重要でした。

これはあまりうまく拡張できません。スレッドの数が多いということは、VM がコンテキストの切り替えに多くの時間を費やす必要があることを意味し、各スレッドが独自のスタック領域を必要とするため、メモリの使用量が多くなります。パイプライン方式で処理するスレッドの数を少なくするか、非同期技術でスレッド プールを使用することをお勧めします。

スレッドが多いとスタック領域が多くなり、メモリを消費します。-Xss 設定を確認してどれだけの量になるかを計算してください。

そして、何らかの理由でnotifyAll()を実行する必要がある場合は、当然、追加のスレッドの負荷を起動することになりますが、提案されているアーキテクチャではそれを行う必要はないかもしれません。

このモデルでリスニング ソケットごとに 1 つのスレッドを使用することを簡単に回避できるかどうかはわかりません (ただし、私は NIO についてほとんど知りません。これでその問題も解決できるかもしれません)。 java.util.concurrent.Executor インターフェイスとその実装クラスを使用して、余分なスレッドが滞留するのを避ける適切な方法を提供します。確かに、 ThreadPoolExecutor これは、リスニング スレッドを管理するのにも良い方法かもしれません。そうすれば、不必要にスレッドを作成したり破棄したりするのに多くの時間を費やすことがなくなります。

C、Lua、Python で行ったテストによると、非常に少ないコード行で独自の sleep または wait 関数を作成し、単純な軽量ループを作成できます。到達したい将来の時刻をローカル変数に使用し、while ループで現在のタイムスタンプをテストします。fps を使用するスコープ内にいる場合は、リソースを節約するために wait 関数をフレームごとに 1 回実行するようにします。タイムスタンプは秒に制限されているため、より高い精度が必要な場合は、タイムスタンプの代わりに時計の使用を検討してください。待機関数に追加するコードの行数が増えると、精度が低くなり、より多くのリソースが消費されますが、10 行未満であれば十分に速いはずです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top