如何强制收集内存流的底层缓冲区?



>我正在使用内存流,遇到了一些内存不足异常的问题。导致问题的方法如下。

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中的数据即使在处置后也可用。

当然,如果您给出的代码非常准确,那么我建议您删除SerializerStream属性/字段。很少有using语句重用现有属性/变量而不是声明新的局部变量。

using (Stream stream = new MemoryStream(source))
{
    return (T) _formatter.Deserializer(stream);
}

本节使用(Stream = new MemoryStream(source))似乎不正确,您在哪里声明Stream

如果您在使用范围或方法之外引用此变量,则

从使用语句(C# 参考)

您可以实例化资源对象,然后将变量传递给 using 语句,但这不是最佳做法。在这种情况下, 在控件离开使用块后,对象仍保留在范围内,即使 尽管它可能不再有权访问其非托管 资源。换句话说,它将不再完全初始化。如果 您尝试在 using 块之外使用该对象,则可能导致 要抛出的异常。因此,通常最好 在 using 语句中实例化对象并将其范围限制为 使用块。

相关内容

  • 没有找到相关文章