Parallel.ForEach kann eine "Out of Memory" -Ausnahme verursachen, wenn mit einem Enumerable mit einem großen Objekt gearbeitet wird

Ich versuche zu migrieren einer Datenbank, wo die Bilder, wo die in der Datenbank gespeichert, um einen Datensatz in der Datenbank zeigt auf eine Datei auf der Festplatte. Ich versuchte zu verwenden Parallel.ForEach um den Prozess zu beschleunigen mit dieser Methode zur Abfrage der Daten.

Jedoch bemerkte ich, dass ich immer ein OutOfMemory Ausnahme. Ich weiß Parallel.ForEach wird eine batch-Abfrage von enumerables zur Milderung der Kosten für overhead -, wenn es eine für den Abstand der Abfragen aus (also deine Quelle mehr wahrscheinlich wird der nächste Datensatz im Arbeitsspeicher zwischengespeichert, wenn Sie eine Reihe von Abfragen auf einmal anstelle von Abstand Sie aus). Das Thema ist aus einem der Datensätze, die ich fahre ist ein 1-4Mb byte-array, das Zwischenspeichern ist, die den gesamten Adressraum verwendet werden (Das Programm muss laufen in x86-Modus als target-Plattform die 32-bit-Maschine)

Gibt es eine Möglichkeit zum deaktivieren der Zwischenspeicherung oder machen kleinere für die TPL?


Hier ist ein Beispielprogramm, um zu zeigen das Problem. Diese müssen beachtet werden im x86-Modus, um zu zeigen, das Problem, wenn es zu lange oder es ist nicht passiert, auf Ihrem Computer bump up der Größe des Arrays (fand ich 1 << 20 dauert etwa 30 Sekunden, auf meinem Rechner und 4 << 20 war fast augenblicklich)

class Program
{

    static void Main(string[] args)
    {
        Parallel.ForEach(CreateData(), (data) =>
            {
                data[0] = 1;
            });
    }

    static IEnumerable<byte[]> CreateData()
    {
        while (true)
        {
            yield return new byte[1 << 20]; //1Mb array
        }
    }
}
Kommentar zu dem Problem - Öffnen
Wie viele threads aktiv sind, während diese ausgeführt wird? Würde die Einstellung ParallelOptions.MaxDegreeOfParallelism - Wert helfen? Kommentarautor: Kevin Pullin
@Kevin Pullin Dort, wo 9 Aufgaben laufen mit dem Beispiel-code zur Zeit die Ausnahme (bei mir läuft diese auf einem quad core). Wenn er auf max 2 und die array-Größe auf 4 MB, es stabilisiert sich auf Arbeiten rund 64Mb. Post dies als eine Antwort, und ich werde upvote. Ich denke, dies zu tun oder nicht mit TPL kann meine einzige option. Ich lasse es über Nacht laufen mit diesen Einstellungen und sehen, ob ich immer noch die Ausnahme. Kommentarautor: Scott Chamberlain

InformationsquelleAutor der Frage Scott Chamberlain | 2011-08-08

Schreibe einen Kommentar