2017-01-05 24 views
0

私はmemoryappenderでlog4netを使用しています。 すべての行を変数(ここではStringBuilder)に読み込もうとすると、行数が多いときにOutOfMemory-Exceptionが発生します。私は単純にlog4netのコンポーネントのすべてが正常に動作せずにStringBuilderに一万行を追加するときに、私はまた、これを使用しようとした...log4net memoryappenderメモリ不足

public class RenderingMemoryAppender : MemoryAppender 
{ 
    public IEnumerable<string> GetRenderedEvents(List<Level> levelList = null) 
    { 
     foreach (var loggingEvent in GetEvents()) 
     { 
      yield return RenderLoggingEvent(loggingEvent); 
     } 
    } 

    public byte[] GetEventsAsByteArray(List<Level> levelList=null) 
    { 
     var events = GetRenderedEvents(levelList); 
     var s = new StringBuilder(); 
     foreach (var e in events) 
     { 
      s.Append(e); 
     } 
     //the exception is thrown here below when calling s.ToString(). 
     return Encoding.UTF8.GetBytes(s.ToString()); 
    } 
} 

を:私は1mioラインでそれをテストしてみました:

var stringBuilder = new StringBuilder(); 
var stringWriter = new StringWriter(stringBuilder); 

foreach (var loggingEvent in GetEvents()) 
{ 
    stringBuilder.Clear(); 
    loggingEvent.WriteRenderedMessage(stringWriter); 

    list.Add(stringBuilder.ToString()); 
} 

しかし、これも機能しませんでした。

+1

[StringBuilder.ToString()の可能な複製はOutOfMemory Exceptionをスローする](http://stackoverflow.com/questions/25010604/stringbuilder-tostring-throws-outofmemory-exception) – raven

答えて

0

メモリにこのような行がたくさんある場合、ランタイムは文字列全体を含むことができるメモリを割り当てる必要があります。その時点で可能でない場合は、OutOfMemory例外がスローされます。 Memorystreamからバイトが必要な場合は、MemorystreamでToArray()メソッドを呼び出す方が効率的です.ToStringメソッドがStringBuilderで失敗するのと同じ理由で失敗することもあります。あなたが64ビットモードで動作しているかどうかを確認することができます。そうでない場合は、より多くのアドレス空間を取得するのに役立ちます。あなたのログ記録方法を再考する助言があります。あなたが今やっているやり方は信頼できず、あなたのプログラムを壊すことさえあります。