2016-07-15 3 views
3

ウェブサーバーなどのマルチスレッド設定では.NETで、一般的に85KBを超える連続したメモリブロックを作成しないようにしています。そのため、大きなオブジェクトヒープになる可能性があります。フラッシングせずに連続してストリームに書き込むと、内容をラージオブジェクトヒープに強制的に書き込むことができますか?

私の同僚の開発者の1人がループを使用してResponseに書き込みました。 OutputStream、ループの終わりを除いてFlushなし。

ループでFlushがメモリの問題につながる可能性があると私は考えていますか?どのように私はこれを証明することができますか?

答えて

1

これは、使用されているストリームの実装の詳細によって異なります。 Stream base class

上のMSDNドキュメントからのストリームは、ファイル、入力/出力装置、プロセス間通信パイプ、またはTCP/IPソケットなどのバイトのシーケンスの抽象化です。 Streamクラスとその派生クラスは、これらの異なる入出力タイプの一般的なビューを提供し、オペレーティングシステムとその基礎となるデバイスの特定の詳細からプログラマーを分離します。

そのストリームの作成者は、我々はそれがあなたのためにそれらのフラッシング詳細を処理しなければならないと仮定し、複数のその後のWriteの呼び出しに対処する方法上の任意の追加のガイダンスを残さなかった場合。

私はこの答えが少し残念だと思うので少し深く掘り下げてください。あなたの同僚がResponse.OutputStreamを使用していると言えば、そのプロパティの基礎となる実装が何であるかを見てみましょう。

get 
{ 
    if (!this.UsingHttpWriter) 
    { 
     throw new HttpException(SR.GetString("OutputStream_NotAvail")); 
    } 
    return this._httpWriter.OutputStream; 
} 

だから、_httpWriterで何かからStreamを使用しています。そのフィールドはHttpWriterのインスタンスへの参照を保持することが分かります。それは、OutputStreamプロパティは、コンストラクタで初期化されますです:

this._stream = new HttpResponseStream(this); 

クラスHttpResponseStreamは内部にあるが、我々はオープン、それをてこのようにILSpyを使用することができます。あなたがバイトを見ることができるように[]のデータは、さらに助けHttpResponseUnmanagedBufferElementコピーバイトのデータをコピーして保存する方法に渡されている

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(); 
    } 
} 

:そのWrite方法は戻って、このHttpWriterのメソッドに実装を延期しますアンマネージメモリであるバッファにMarshal.Copyのバッファを追加します。そのメモリは、統合されたパイプラインの場合は約16Kブロック、残りのパイプラインの場合は約31Kブロックで割り当てられているようです。

これで、Streamは内部構造がLOH上に終わるほど多くのメモリを割り当てるとは思っていませんが、それは見た目では管理されていないメモリコピーしか作成しないからです。

定期的に電話でFlushを呼び出すことをお勧めします。 HttpResponseStreamは、この実装を持っている:

_writer以前は HttpWriterを発見され
public override void Flush() 
{ 
    this._writer.Flush(); 
} 

。その実装は、フラッシュが唯一のCPUサイクルを無駄に呼び出して、右である

public override void Flush() 
{ 
} 

です。これは、有望なdocumentation in MSDNにもかかわらず、早急にバッファをクリアする際にストリームを助けません。

+0

正しいと思われます。http://referencesource.microsoft.com/#System.Web/HttpWriter.cs,0373c8927b6c5833 - Flushが何もしないのは面白いことです。ありがとう! – user420667

関連する問題