如何重用MemoryStream
我的代码使用 MemoryStream
将对象序列化到网络/从网络反序列化。我想在我的班级中重复使用一个 MemoryStream
,而不是每次需要时创建一个新的 通过线路发送一些东西。
有谁知道该怎么做?
代码片段:
// 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;
}
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您的序列化方法有一个错误:
即数组返回大于序列化数据
对于反序列化,您可以构造一个使用传入数组的内存流,因此它不会分配内部缓冲区。但除非你有基准测试表明内存流分配确实是一个瓶颈,否则我不会打扰。
如果您确实想优化内存分配,则需要重用
byte[]
缓冲区。这尤其意味着修改 API 以处理数组的子部分,因此消息大小和数组大小不需要相同。以下是可以随时更改的实现细节(并且自从我阅读后可能已经更改):
如果缓冲区最终没有出现在大对象堆上,那当然不值得打扰。如果对象很小,它们将在下一个 Gen0 收集中以低廉的价格收集。另一方面,大对象堆直接以 Gen2 结束。大于 250kB 的 AFAIR 对象被分配在那里。
当然,在不缩小缓冲区的情况下重用它们可能会导致内存泄漏。
First of all your serialize method has a bug:
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.
重复使用相同的
MemoryStream
不会给您带来任何性能优势。MemoryStream
没有明确的原因是有的。因为清除它比创建一个新的成本更高。如果您查看该类的内部结构,您可以看到它分配了一个缓冲区,并且在写入时,如果其缓冲区已满,它将分配新的缓冲区并复制现有字节,然后继续。 因此在某种程度上,缓冲区是不可变的。
这可以在撰写本文时通过
EnsureCapacity()
调用的容量设置中看到:Reusing same
MemoryStream
does not give you any performance benefit.There is a reason why
MemoryStream
does not have a clear. Because it would be more expensive to clear it than to create a new one.If you look at the internals of the class, you can see that it allocates a buffer, and when writing, if its buffer gets full, it allocates new buffer and copy existing bytes and then carries on. So in a way the buffer is immutable.
This can be seen here at the setting of the capacity which is called by
EnsureCapacity()
at the time of writing: