Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

want to re-use MemoryStream

My code uses MemoryStream to serialize/deserialize objects to/from the network. I would like to re-use a single MemoryStream in my class, rather than create a new one each time I need to send something over the wire.

Does anyone know how to do this?

Code snippet:

    // Serialize object to buffer
    public  byte[] Serialize(object value)
    {
        if (value == null)
            return null;
      MemoryStream _memoryStream = new MemoryStream();

        _memoryStream.Seek(0, 0);
        _bf.Serialize(_memoryStream, value);
        return _memoryStream.GetBuffer();
    }

    // Deserialize buffer to object
    public  object Deserialize(byte[] someBytes)
    {         
        if (someBytes == null)
            return null;
        MemoryStream _memoryStream = new MemoryStream();
        _memoryStream.Write(someBytes, 0, someBytes.Length);
        _memoryStream.Seek(0, 0);
        var de = _bf.Deserialize(_memoryStream);
        return de;
    }

Thanks!

like image 907
Jacko Avatar asked Jan 07 '11 19:01

Jacko


People also ask

Do I need to dispose MemoryStream?

MemoryStream does not have any unmanaged resources to dispose, so you don't technically have to dispose of it. The effect of not disposing a MemoryStream is roughly the same thing as dropping a reference to a byte[] -- the GC will clean both up the same way.

How do I know if MemoryStream is empty?

Check the Length property of the stream. Length represents the number of bytes currently in the file. If it is 0, the file is empty.

How do you save on MemoryStream?

Save MemoryStream to a String Steps follows.. StreamWriter sw = new StreamWriter(memoryStream); sw. WriteLine("Your string to Memoery"); This string is currently saved in the StreamWriters buffer.

What is the difference between Stream and MemoryStream?

You would use the FileStream to read/write a file but a MemoryStream to read/write in-memory data, such as a byte array decoded from a string. You would not use a Stream in and of itself, but rather use it for polymorphism, i.e. passing it to methods that can accept any implementation of Stream as an argument.


1 Answers

First of all your serialize method has a bug:

Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.

i.e. the array returns is larger than the serialized data

For deserializing you can construct a memory stream which uses the passed in array, so it won't allocate internal buffers. But unless you have benchmarks which show that memory stream allocation is really a bottleneck I wouldn't bother.

If you really want to optimize your memory allocations you'll need to reuse the byte[] buffers. This in particular means modifying the api to work with subsections of arrays so the message size and array size don't need to be identical.

The following are implementation details which can change at any time(and might already have changed since I read about it):
It's surely not worth bothering if the buffers don't end up on the large object heap. If the objects are small they'll be cheaply collected on the next Gen0 collection. The large object heap on the other hand directly ends up in Gen2. AFAIR objects >250kB are allocated there.

And of course reusing the buffers without ever shrinking them can be a memory leak.

like image 72
CodesInChaos Avatar answered Sep 22 '22 06:09

CodesInChaos