【问题标题】:How do I force collection of a MemoryStream's underlying buffer?如何强制收集 MemoryStream 的底层缓冲区?
【发布时间】:2013-09-12 13:58:56
【问题描述】:

我正在处理内存流,并且遇到了一些内存不足异常的问题。导致问题的方法如下。

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 语句,但问题仍然存在。谢谢你的收获。

【问题讨论】:

  • 同意@astander,流应该是本地的和/或发布时代码被损坏。
  • 调用代码示例似乎也是错误的。请准确无误,尤其是关于声明缓冲区和资源对象的方式/位置。
  • @HenkHolterman:特别是“调用”代码不会调用Deserialize :)
  • 不,但我假设该对象具有重写的反序列化。不清楚。
  • 对不起,我在检索类中添加了调用。

标签: c# memory-management memory-leaks memorystream disposing


【解决方案1】:

当您将字节数组传递给MemoryStream 构造函数时,该字节数组缓冲区。也许您仍然在调用代码中保留对该字节数组的引用?

您显示的代码不会保留数据(假设它实际上分配了一个局部变量,而不是分配给一个属性) - 并处理流在这里绝对不重要,而且根本无济于事……MemoryStream 中的数据即使在处理后仍然可用。

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

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

【讨论】:

  • 那么,将传入的byte[] 明确设置为null 在使用后会解决这个问题吗?
  • @elucid8:也许,也许不是——我们没有几乎足够的关于情况的信息可以说,你甚至没有说你会把它设置在哪里空值。在Deserialize 方法中将其设置为空肯定不会有任何效果。
  • 乔恩,事实证明字节数组只是因为序列化程序本身而被保留。我按照你的建议做了,它解决了这个问题。感谢您的帮助!
【解决方案2】:

这部分似乎不对使用 (Stream = new MemoryStream(source)),你在哪里声明 Stream

如果您在使用范围或方法之外声明此变量,那么

来自using Statement (C# Reference)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 1970-01-01
    相关资源
    最近更新 更多