MemoryStreamをバッファにしてメモリリークするところでした
Socketから流れてくるデータをあるバイト列で分割して処理するために、読み取りブロックを超えるデータを保持しておくバッファを設けたんですね。
byte[] buf = new byte[256]; MemoryStream s = new MemoryStream(); ... //とりあえず受信したデータを積んで、 s.Write(buf, 0, buf.Length); if(/*データが揃った*/) { var bytes = s.ToArray(); s.Close(); s = new MemoryStream(); ... }
毎回MemoryStream作り直してるし複数の場所で同じことしてるしでイマイチなんですが、それでも溜めたデータを破棄しているので致命的な問題はありません。
でもこのコード書いたとき、ClearするのはToArrayしているからであってReadしたら必要ないと考えていた気がするんです。
if(/*データが揃った*/) { var bytes = new byte[s.Length - s.Position]; s.Read(bytes, 0, bytes.Length); ... }
何が問題ってMemoryStreamにデータがたまり続ける。
NetworkStreamなどのシークできないStreamは一度読んだデータは二度と読めないんですが、MemoryStreamはシークできるStreamです。SeekでPosition移動してやれば一度読んだデータも読めます。
つまりReadしたデータは保持されているわけで、放置すればメモリリークですね万歳。
代わりに何使いましょう
改めて考えると、読み終わった部分を詰めるのはそれなりにコストがかかります。じゃあバッファに向かないじゃん。
そこで今回ご紹介するのが循環バッファもといQueueです!
そんなに悪くないとは思ったのだけど、一要素ずつしか読み書きできないから効率悪いなーと思ってググったら既出でした。
http://stackoverflow.com/questions/8221136/fifo-queue-buffer-specialising-in-byte-streams
ちょっとオーバースペック気味にも思えるから自分で書くかというオチ。。