2016-08-10 2 views
1

In der Hoffnung, dass jemand mir helfen kann, habe ich keine Ideen mehr!Abfangen einer OutOfMemory-Ausnahme C#

Ich habe eine intensive Methode, die ein Objekt erstellt und es in eine Warteschlange stellt. Es sieht viel wie:

private void LongMethod() 
    { 
    for (int i=0; i<number;i++) 
    { 
     for (int j=0; j<number; j++) 
     { 
     object o = new object(); 
     queue.enqueue(o); 
     } 
    } 
    } 

Aber manchmal number einen sehr großen Wert hat und so in Abhängigkeit von der Größe des verfügbaren Speichers, das manchmal löst eine OutOfMemory Ausnahme.

Also, was ich habe versucht, ist, dies zu tun:

private bool CheckingMethod(number) 
{ 
long initialValue = System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; 

object o = new object(); 
queue.Enqueue(o) 

long difference = initialValue - System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; 

if(Microsoft.VisualBasic.Devices.ComputerInfo.TotalPhysicalMemory <= difference * number * number) 
    { 
    return true; 
    } 
    return false; 
} 

Und dann kann die anrufende Methode tun:

private void CallingMethod(number) 
    { 
    if(CheckingMethod(number) 
     { 
     LongMethod(number); 
     } 
    } 

ich vor dem Ausführen des longMethod zu überprüfen bin versucht, ob es verursacht eine OOM-Ausnahme. Mein Problem ist, dass difference mir einen drastisch anderen Wert geben wird und ich daher manchmal immer noch die outOfMemory Ausnahme. Gibt es einen besseren Weg, dies zu tun?

+0

Wie groß ist "Nummer"? Wie groß sind die Objekte, die Sie zuweisen? –

+0

Die Wahl des richtigen Datentyps ist der richtige Weg ... –

+0

@MitchWheat Nummer ist eine Benutzereingabe, und die Idee ist es, die höchste 'Zahl' möglich zu machen, ohne eine Ausnahme zu werfen. Das versuche ich herauszufinden. Ich möchte wissen, wie viel Speicher jedes Objekt verwendet. –

Antwort

3

Es kann gut sein, dass Sie diesen Algorithmus neu entwerfen müssen, so dass es nicht versucht, "alles" in eine Warteschlange zu stellen ... oder vielleicht überhaupt keine Warteschlange verwendet. Zum Beispiel könnte ein Iterator hier verwendet werden?

Die Logik von LongMethod, die gegenwärtig als Doppel verschachtelte Schleife exprimiert wird, könnte äquivalent als Algorithmus ausgedrückt werden, die (a struct irgendeine Art gegeben zwischen Anruf „Zustand zu halten“), kehrt (oder "ergibt") ein neues object() jedes Mal.

Eine erneute Darstellung dieses Algorithmus würde Sie von der Verpflichtung befreien, eine enorme Anzahl von Objekten "auf einmal" zu erzeugen und sie "auf einmal" in eine Warteschlange zu stellen. Stattdessen könnte es möglich sein, die Objekte nach Bedarf "on demand" zu erzeugen und/oder "einige" Objekte zu erzeugen und in die Warteschlange einzureihen, während die Fähigkeit beibehalten wird, zu einem späteren Zeitpunkt "mehr von ihnen" zu erzeugen.

Sie können wirklich nicht eine OOM-Ausnahme "fangen":  , wenn so etwas passiert, "das Programm ist bereits neun Zehntel tot im Wasser, und fast sicher, schnell zu ertrinken." Sie benötigen eine Art von Redesign des Algorithmus, die die Notwendigkeit einer "so großen Warteschlange" überflüssig macht.