Heap-Fragmentierung bei der Verwendung von byte-arrays
Ich habe ein C# 4.0-Anwendung (single-producer/single consumer), die transfers riesige Menge von Daten in Blöcken. Es gibt zwar keine neue Speicherzuweisung I run out of memory nach einer Weile.
Ich profilierte Speicher mit Redgate Speicher-profiler und es gibt eine Menge freien Speicher gibt. Es sagt, dass der freie Speicher nicht eingesetzt werden, weil der Fragmentierung.
Verwende ich eine Blockierung Auflistung als Puffer-und byte-arrays als Mitglieder:
BlockingCollection<byte[]> segments = new BlockingCollection<byte[]>(8);
//producer:
segments.Add(buffer);
//consumer:
byte[] buffer = _segments.Take();
Wie kann ich verhindern, dass ich es geschafft die Fragmentierung des Speichers?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du wahrscheinlich lief in dem large object heap-problem - Objekte, die größer sind als 85.000 Byte beträgt, werden auf dem large object heap, die nicht komprimiert wird, die führen kann zu seltsamen out-of-memory-Situationen. Obwohl Sie anscheinend die Leistung in .NET 4 wurde verbessert, es ist bei weitem nicht perfekt. Die Lösung ist im Grunde verwenden Sie Ihre eigenen Puffer-pool, die enthält ein paar statisch reservierte Speicherbereiche und verwenden diese.
Es gibt eine ganze Reihe von Fragen, etwa, dass auf SO.
Update: Microsoft bietet eine Puffer-manager als Teil des WCF-stack. Es ist auch auf codeproject.
static
Puffer-manager für alle Instanzen von Daten-Transporter oder ein singleton oder eine Instanz Mitglied pro Daten-transporter (jedes Daten-transporter lebt für 2-3 Stunden und es sind 1000 von Ihnen, jeder nutzt 8x256 KB Speicher)Wie lang sind die byte [] - array? Tun Sie fallen in das kleine Objekt oder large object heap? Wenn Sie erleben eine Fragmentierung des Speichers, ich würde sagen, Sie fallen in der LOH.
Sollten Sie daher die Wiederverwendung der gleichen byte-arrays (verwenden Sie einen pool) oder verwenden Sie kleinere Stücke. LOH ist nie verdichtet, so kann es ziemlich fragmentiert. Leider gibt es keine Möglichkeit, um dieses. (Abgesehen von zu wissen, diese limitation zu vermeiden)
Den GC nicht kompakt der large object heap für Sie, können Sie immer noch programmatisch verdichten. Der folgende Codeausschnitt zeigt, wie dies erreicht werden kann.