1

我在我的 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 在释放缓冲区时返回它。

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

4

1 回答 1

0

The BufferManager is normally used in scenarios where you must prevent GC pressure - where there are a lot of small byte[] assignments, like when receiving or sending data on a very low level (e.g. sockets). The emphasis here is on a lot, otherwise the GC should be able to handle the memory allocations just fine.

To prevent the loading of the entire converted document file into memory you should use the FileStream directly (without reading it's entire content into memory - a byte[]) in combination with the streamed (response) TransferMode, if possible.

于 2013-02-03T00:10:35.007 回答