私はいくつかのコードを持っています:
ReadableByteChannel
a から aに読み込みByteBuffer
、- 転送されたバイトを記録し、
- 数十から数百ミリ秒休止し、
ByteBuffer
をに渡しWritableByteChannel
ます。
いくつかの詳細:
- どちらのチャネルも TCP/IP ソケットです。
- 合計接続読み取りサイズは数十メガバイトです。
- ソース ソケット (
ReadableByteChannel
からバイトを取得している) が同じマシン上にある。 - HP DL380s 上の Debian Lenny 64 ビット
- Sun Java 1.6.0 アップデート 20
問題は、 ByteBuffer がどれだけ大きく割り当てられていても、 または のいずれかで.allocate()
、.allocateDirect()
ByteBuffer に読み取られるバイト数が 8KB で最大になることです。私のターゲット ByteBuffer サイズは 256KB です。これはごく一部 (1/32) しか使用されていません。約 10% の時間で 2896 バイトしか読み込まれません。
OS の TCP バッファ設定を確認しましたが、問題ないようです。これは、バッファ内のバイト数に関する netstat のレポートを見ることで確認できます。両方とも、ソケット バッファ内に 8KB を超えるデータがあります。
tcp 0 192384 1.2.3.4:8088 1.2.3.4:53404 ESTABLISHED
tcp6 110144 0 1.2.3.4:53404 1.2.3.4:8088 ESTABLISHED
ここで際立っているのは、TCP と TCP6 の混在ですが、それは問題ではないと思います。上記の出力では、私の Java クライアントはポート 53404 にあります。
遅延よりも帯域幅を優先するようにソケットのプロパティを設定しようとしましたが、変更はありません。
Socket socket = new Socket(host.getHostName(), host.getPort());
socket.setPerformancePreferences(1, 0, 2); //bw > connection time > latency
の値をログに記録するとsocket.getReceiveBufferSize()
、一貫してわずか 43856 バイトと報告されます。思ったより小さいですが、それでも 8KB を超えています。(これはまた、私が予想していたであろう非常に丸い数ではありません。)
ここで何が問題なのか、私は本当に困惑しています。理論的には、知る限り、これは起こるべきではありません。ストリームベースのソリューションに「ダウングレード」することは望ましくありませんが、ソリューションが見つからない場合は、ストリーム ベースのソリューションに移行します。
私は何が欠けていますか?修正するにはどうすればよいですか?