C# 在不刷新的情况下连续写入流会将其内容强制到大型对象堆上吗?

C# 在不刷新的情况下连续写入流会将其内容强制到大型对象堆上吗?,c#,asp.net,memory,streaming,large-object-heap,C#,Asp.net,Memory,Streaming,Large Object Heap,在多线程设置中,例如在.NET中的Web服务器,我通常会尝试避免创建占用85KB以上的连续内存块,因为这可能会导致大型对象堆出现内存问题 我的一个开发伙伴正在使用循环写入响应输出流,除循环结束外,不进行刷新 我认为循环中不刷新会导致内存问题,这是正确的吗?我如何证明这一点?这取决于所用流的实现细节。从上的MSDN文档 流是字节序列的抽象,例如文件、输入/输出设备、进程间通信管道或TCP/IP套接字。流类及其派生类提供了这些不同类型输入和输出的通用视图,并将程序员与操作系统和底层设备的特定细节隔离

在多线程设置中,例如在.NET中的Web服务器,我通常会尝试避免创建占用85KB以上的连续内存块,因为这可能会导致大型对象堆出现内存问题

我的一个开发伙伴正在使用循环写入
响应
<代码>输出流,除循环结束外,不进行刷新


我认为循环中不刷新会导致内存问题,这是正确的吗?我如何证明这一点?

这取决于所用流的实现细节。从上的MSDN文档

流是字节序列的抽象,例如文件、输入/输出设备、进程间通信管道或TCP/IP套接字。流类及其派生类提供了这些不同类型输入和输出的通用视图,并将程序员与操作系统和底层设备的特定细节隔离开来

如果该流的实现者没有就如何处理多个后续
Write
调用留下任何额外的指导,我们应该假设它为您处理这些刷新细节

我想你会觉得这个答案有点令人失望,所以再深入一点。正如您所说,您的同事正在使用,让我们看看该属性的底层实现是什么

get
{
    if (!this.UsingHttpWriter)
    {
        throw new HttpException(SR.GetString("OutputStream_NotAvail"));
    }
    return this._httpWriter.OutputStream;
}
因此,它使用的是来自
\u httpWriter
流。该字段原来包含对实例的引用。它是在构造函数中初始化的
OutputStream
属性:

this._stream = new HttpResponseStream(this);
HttpResponseStream
是内部的,但我们可以使用ILSpy将其撬开。它的
Write
方法将实现推迟到这个HttpWriter的方法:

internal void WriteFromStream(byte[] data, int offset, int size)
{
    if (this._charBufferLength != this._charBufferFree)
    {
        this.FlushCharBuffer(true);
    }
    this.BufferData(data, offset, size, true);
    if (!this._responseBufferingOn)
    {
        this._response.Flush();
    }
}
如您所见,字节[]数据被传递给一个方法,该方法通过帮助
HttpResponseUnmanagedBufferElement
进一步复制和存储数据,该帮助使用
Marshal将字节复制到内存中。将
复制到非托管内存的缓冲区中。对于集成管道,该内存似乎是以16K左右的块分配的,而对于其余部分,则是以31K左右的块分配的

因此,我不希望流分配太多内存,以致其内部结构最终出现在LOH上,因为从外观上看,它只生成托管->非托管内存拷贝

让我们知道你的想法,定期在循环中调用
Flush
HttpResponseStream
具有以下实现:

public override void Flush()
{
    this._writer.Flush();
}
其中
\u writer
是较早发现的
HttpWriter
。它的实施非常困难

public override void Flush()
{
}
没错,调用flush只会浪费CPU周期。它不会帮助流更快地清除其缓冲区,尽管这很有希望。

看来你是对的:-多么有趣的是,Flush什么都不做。谢谢