WCF BufferManager ReturnBuffer vs. Clear

时间:2013-02-01 15:13:33

标签: wcf buffer-manager

我在WCF服务中使用BufferManager。我创建了自己的类来包装实现IDisposable的BufferManager。现在,我的Dispose方法如下所示:

public void Dispose()
    {
        this.bufferManager.Clear();
    }

我的问题:这是否与在管理员使用的所有缓冲区上调用ReturnBuffer完成相同的操作?

仅供参考:我在以下方法中使用BufferManager:

public byte[] ReadAllBufferedBytes(string filePath)
    {
        using (var fileStream =
            new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            byte[] buffer = this.bufferManager.TakeBuffer((int)fileStream.Length);

            fileStream.Read(buffer, 0, buffer.Length);

            return buffer;
        }
    }

我这样做的原因是因为我不断获得OutOfMemory异常会导致服务中断。

主机服务器有3 GB内存。该服务处于InstanceContextMode.Single模式,因此一次处理一个图像。图像以字节数组的形式接收 - 最大可能是100MB,但通常要小得多 - 转换后,然后作为字节数组返回。大对象堆上最终会出现很多问题,图像大小会有很大差异。

我想知道问题是否是堆碎片。

当文档的每个页面都被转换时,它会附加到磁盘上的临时文件中。转换后,我将整个转换后的文件从磁盘读入一个字节数组并将其返回给客户端。

标准的File.ReadAllBytes方法在从文件中读取时会创建一个新的字节数组,由于我正在使用的图像大小,它不可避免地会在LOH上结束(我假设这是发生的事情)。我创建了ReadAllBufferedBytes方法来做同样的事情,但是缓冲字节数组并让BufferManager在处理时返回缓冲区。

另一个问题是:我甚至需要做这一切吗?

1 个答案:

答案 0 :(得分:0)

BufferManager通常用于必须防止GC压力的情况 - 有很多的小byte[]分配,例如在非常低的级别接收或发送数据时(例如插座)。这里的重点是很多,否则GC应该能够很好地处理内存分配。

为了防止将整个转换后的文档文件加载到内存中,您应该直接使用FileStream(不将其全部内容读入内存 - 一个byte [])与streamed (response) TransferMode一起使用,如果可能的话。