>我正在使用内存流,遇到了一些内存不足异常的问题。导致问题的方法如下。
public override T Deserialize<T>(byte[] source)
{
using (var stream = new MemoryStream(source))
{
var result = (T)_formatter.Deserialize(stream);
return result;
}
}
这是一个典型的调用:
var bufferSize = binaryArrays.Sum(x => x.Length);
var streamBuffer = new byte[bufferSize];
using (var stream = new MemoryStream(streamBuffer))
{
foreach (var binaryArray in binaryArrays)
{
stream.Write(binaryArray, 0, binaryArray.Length);
}
result = serializer.Deserialize<T>(stream.ToArray());
}
我已经在此方法的包含类中实现了IDisposable
,并且我显式释放了流(即使它不是必需的),但我无法回收我的内存。我知道这是因为 MemoryStream 的底层缓冲区仍然浮动,并且我的应用程序的虚拟内存已经耗尽。那么,如何杀死底层缓冲区呢?有什么技术可以在这里使用吗?
非常感谢。
[编辑]
我修复了 using 语句,但问题仍然存在。谢谢你的收获。
将字节数组传递给MemoryStream
构造函数时,该字节数组就是缓冲区。也许您仍然在调用代码中保留对该字节数组的引用?
您显示的代码不会保留数据(假设它实际上是分配局部变量,而不是分配给属性) - 并且处理流在这里绝对不重要,并且根本没有帮助......无论如何,MemoryStream
中的数据即使在处置后也可用。
当然,如果您给出的代码非常准确,那么我建议您删除Serializer
并Stream
属性/字段。很少有using
语句重用现有属性/变量而不是声明新的局部变量。
using (Stream stream = new MemoryStream(source))
{
return (T) _formatter.Deserializer(stream);
}
本节使用(Stream = new MemoryStream(source))似乎不正确,您在哪里声明Stream?
如果您在使用范围或方法之外引用此变量,则
从使用语句(C# 参考)
您可以实例化资源对象,然后将变量传递给 using 语句,但这不是最佳做法。在这种情况下, 在控件离开使用块后,对象仍保留在范围内,即使 尽管它可能不再有权访问其非托管 资源。换句话说,它将不再完全初始化。如果 您尝试在 using 块之外使用该对象,则可能导致 要抛出的异常。因此,通常最好 在 using 语句中实例化对象并将其范围限制为 使用块。