在.NET中的多线程设置(如heap服务器)中,我通常试图避免创建占用更多感谢85 on的连续内存块,因为这可能会导致大对象堆上的结果,从而导致内存问题。
我的一位同事正在使用一个循环来编写Response。OutputStream,除循环结束外,不使用Flush。
我是否正确地认为循环中的Flush不可能导致内存问题?我怎么能证明这一点?
发布于 2016-07-18 20:13:47
这取决于正在使用的流的实现细节。来自流基类上的MSDN文档
流是字节序列的抽象,例如文件、输入/输出设备、进程间通信管道或TCP/IP套接字。Stream类及其派生类提供了这些不同类型的输入和输出的通用视图,并将程序员与操作系统和底层设备的特定细节隔离开来。
如果该流的实现者没有留下任何关于如何处理多个后续Write调用的额外指导,我们应该假设它为您处理这些刷新细节。
我想你会觉得这个答案有点令人失望,所以再深入一点。正如您所说的,您的同事正在使用Response.OutputStream,让我们看看该属性的底层实现是什么。
get
{
if (!this.UsingHttpWriter)
{
throw new HttpException(SR.GetString("OutputStream_NotAvail"));
}
return this._httpWriter.OutputStream;
}因此,它使用的是来自于Stream在_httpWriter中的东西。该字段最终保存了对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();
}
}如您所见,byte[]数据正被传递给一个方法,该方法进一步复制数据并使用help HttpResponseUnmanagedBufferElement存储数据,帮助HttpResponseUnmanagedBufferElement将字节与Marshal.Copy复制到非托管内存的缓冲区中。该内存似乎以16 K左右的块分配给集成管道,其余部分则分配到31K左右。
有了这一点,我不希望流分配太多内存,以至于其内部结构在LOH上结束,因为从外观上看,它只会产生托管->非托管内存副本。
给我们留下了你定期在循环中调用Flush的想法。HttpResponseStream有这样的实现:
public override void Flush()
{
this._writer.Flush();
}其中_writer是早期发现的HttpWriter。它的实施是
public override void Flush()
{
}这是正确的,调用刷新只会浪费CPU周期。尽管有希望的MSDN文档,它也不会帮助流更快地清除它的缓冲区。
https://stackoverflow.com/questions/38405934
复制相似问题