ReadableByTechannel.Read(bytebuffer dest)8kbでキャップされた読み取り。なんで?
-
02-10-2019 - |
質問
私はいくつかのコードを持っています:
- aから読みます
ReadableByteChannel
にByteBuffer
, - 転送されたバイトに注意してください、
- 数十から数百のミリ秒を一時停止し、
- に合格します
ByteBuffer
にWritableByteChannel
.
いくつかの詳細:
- 両方のチャネルはTCP/IPソケットです。
- 合計接続読み取りサイズは、数十メガバイトです。
- ソースソケット(
ReadableByteChannel
からバイトを取得しています)は同じマシンにあります。 - HP DL380SのDebian Lenny 64ビット
- Sun Java 1.6.0アップデート20
問題は、どんなに大きくても、bytebufferが割り当てられていても、 .allocate()
また .allocateDirect()
, 、8kbでBytebuffer Maxesに読み取られるバイト数。私のターゲット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
ここで際立っていることの1つは、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を超えています。 (それはまた、私が期待していたであろう非常に丸い数ではありません。)
私はここに問題が何であるかについて本当に困惑しています。理論的には、AFAIK、これは起こってはいけません。ストリームベースのソリューションに「ダウングレード」することは望ましくありませんが、ソリューションが見つからない場合は次に進む場所です。
何が足りないの?それを修正するために私は何ができますか?
解決
わかりました、私は問題を見つけました! (そして、誰かが同じ問題を抱えている場合に備えて、私自身の質問に答えています。)
私はインストールしていました ReadableByteChannel
直接からではありません Socket
インスタンスですが、 HttpEntity.getContent()
(Apache HTTP Commonsクライアント)メソッドが返されました InputStream
. 。 HTTP Commonsクライアントは、早い段階でソケットに渡されていました DefaultHttpClientConnection.bind()
方法。私が理解していなかったのは、チャンネルは BufferedInputStream
HTTP Commonsクライアントの実装内に埋もれたインスタンス。 (8kbはたまたまJava 6のデフォルト値です。)
したがって、私の解決策は、をつかむことでした ReadableByteChannel
生のオフ Socket
実例。