独自のメッセージングシステムでSpringリモート処理(Java直列化を使用)を介して通信するクライアントとサーバーがあります。私のサーバーは大きなオブジェクトを返すので、私のSpring Remotingの実装は直列化されたオブジェクトのバイト配列をブロックに分割し、複数のメッセージを送信します。クライアントは与えられた要求に対するすべての応答メッセージを待って、最終的に以下のメソッドを呼び出してバイト配列をデシリアライズして結果のオブジェクトにします。1つの大きな配列に入れないでバイト配列ブロックを逆シリアル化する方法
protected Object deserialize(List<byte[]> blocks) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream(blocks.size() * blockSize);
for (byte[] b : blocks) {
os.write(b, 0, b.length);
}
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
ObjectInputStream objInputStream = new ObjectInputStream(is);
return objInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
これは完全に機能します。しかし、その非常に重い記憶。ブロック
List<byte[]>
含む- :非常に大まかメモリ内のシリアライズされたバイト配列と同じサイズをメモリ内のオブジェクトをされたと仮定すると、私はメモリ内の私のオブジェクトの3倍の大きさのようなもので終わります
ByteArrayOutputStream
には連結バイト配列が含まれています(ByteArrayOutputStream.toByteArray()
は配列をコピーするため別の配列も可能です)。
このメソッドは、すべてのアレイがGC'dすることができ返しますが、このメソッドの呼び出し時のメモリ使用量に大きなスパイクがあります一度
私の質問には:私はそれらを受け取るように私はバイト配列を追加することができますブロッキングバイト入力ストリームを作成する方法はありますか? ObjectOutputStreamは(別のスレッドで)利用可能なバイトを読み込み、さらにバイトが書き込まれるまでブロックし、オブジェクトが完全に非直列化されるまで続行します。このように、私はメモリ内に完全に連結されたバイト配列を持つ必要はありません。標準的なストリームの実装はどれも適合していないようですが、NIOをどのように使用するのか分かりませんし、そこに1つあれば独自のストリーム実装を書くのではないでしょう。あなたはまた、効率化のためにもread(byte[],int,int)
をオーバーライドする必要がありますが、これはゆっくりと少しあれば動作します勿論
多くのおかげで、 イアン
+1これは匿名の内部クラスとして行うべきではありません。 :) – biziclop
私はちょうど一緒に静的な入れ子になった、または完全なクラスでも良いと打ちました –
私はそれがOPのためのアドバイスの言葉だったと思って、やや不器用な言葉。 – biziclop