我正在使用内存流,但是我遇到了一些内存不足异常的问题。导致问题的方法如下。
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的底层缓冲区仍在浮动,我的应用程序的虚拟内存已经耗尽。那么,如何杀死底层缓冲区?我可以在这里使用任何技术吗?
非常感谢。
[编辑]
我修复了使用声明,但问题仍然存在。谢谢你。
答案 0 :(得分:2)
将字节数组传递给MemoryStream
构造函数时,该字节数组是缓冲区。也许你仍然在调用代码中持有对该字节数组的引用?
您显示的代码不会保留数据(假设它实际分配本地变量,而不是分配给属性) - 并且处理流在这里肯定不重要,根本不会有帮助...... MemoryStream
中的数据即使在处理完毕后也可用。
当然,如果您提供的代码非常准确,那么我建议您删除Serializer
和Stream
属性/字段。使用using
语句重用现有属性/变量而不是声明新的局部变量,非常很少是一个好主意。
using (Stream stream = new MemoryStream(source))
{
return (T) _formatter.Deserializer(stream);
}
答案 1 :(得分:0)
此部分似乎不正确使用(Stream = new MemoryStream(source)),您在哪里声明 Stream ?
如果您要将此变量排除在使用范围或方法之外,那么
来自using Statement (C# Reference)
您可以实例化资源对象,然后将变量传递给 使用声明但这不是最佳做法。在这种情况下, 控件离开使用块后,对象仍然在范围内 虽然它可能不再能够访问它的非托管 资源。换句话说,它将不再完全初始化。如果 你试图使用using块之外的对象,你冒险导致 被抛出的异常。出于这个原因,通常更好 在using语句中实例化对象并将其范围限制为 使用块。