6 Stimmen

Erkennen, wann der Speicherplatz knapp wird (Ermittlung des "freien physischen Speichers")

Ich übertrage Bilder von einer Kamera mit hohen FPS in einen Speicherpuffer (eine Liste), und da diese Bilder ziemlich groß sind, geht dem Computer ziemlich schnell der Speicher aus.

Ich möchte die Übertragung für einige Zeit stoppen. der Anwendung der Speicher ausgeht. Bei meinen Tests habe ich festgestellt, dass die Anzeige "Freier physischer Speicher" nahe bei Null liegt.

Das Problem ist nun, dass ich keine Möglichkeit finde, diesen Wert programmatisch abzurufen; in XP wird er nicht einmal irgendwo angezeigt (nur im Vista/7-Taskmanager).

alt text

Ich habe alle Möglichkeiten ausprobiert, die ich finden konnte (WMI, Leistungszähler, MemoryStatus, ...), aber alles, was ich von diesen bekam, war nur der "Verfügbare physische Speicher", was natürlich nicht dasselbe ist.

Irgendwelche Ideen?

Update Leider muss ich die Daten im Speicher haben (ja, ich weiß, ich kann nicht Garantie Es wird im physischen Speicher sein, aber trotzdem), weil die Daten in Echtzeit gestreamt werden und ich eine Vorschau im Speicher sehen muss, nachdem sie dort gespeichert worden sind.

9voto

Eric Lippert Punkte 628543

Korrelation ist keine Kausalität. Auch mit einer Menge an Speicherplatz kann der Speicher "ausgehen". physisch Speicher noch frei. Der physische Speicher ist fast sicher irrelevant; was Ihnen wahrscheinlich ausgeht, ist Adressraum .

Die meisten Menschen denken bei "Speicher" an den Platz, der auf einem Chip verbraucht wird, aber das stimmt schon seit über einem Jahrzehnt nicht mehr. Bei modernen Betriebssystemen kann man sich den Speicher oft besser als eine große Festplattendatei vorstellen, auf der ein großer Hardware-Cache liegt, um sie zu beschleunigen. Physischer Speicher ist nur eine Leistungsoptimierung des plattenbasierten Speichers .

Wenn Ihnen der physische Speicher ausgeht, wird Ihre Leistung schlecht sein. Aber die knappe Ressource ist eigentlich Adressraum die Ihnen ausgeht. Eine große Liste muss einen großen zusammenhängenden Block an Adressraum haben, und es könnte sein, dass kein Block in der gewünschten Größe übrig ist.

Tun Sie das nicht. Ziehen Sie einen Block von vernünftiger Größe herunter, speichern Sie ihn auf der Festplatte und bearbeiten Sie die Datei auf der Festplatte nach Bedarf.

8voto

OwenP Punkte 24128

Ich bin zwar zu spät dran, aber haben Sie schon einmal daran gedacht, die System.Runtime.MemoryFailPoint Klasse? Sie führt eine Reihe von Maßnahmen durch, um sicherzustellen, dass die angeforderte Zuweisung erfolgreich ist, und wirft InsufficientMemoryException, wenn sie fehlschlägt; Sie können dies erkennen und die Übertragung stoppen. Sie können wahrscheinlich eine durchschnittliche Größe der eingehenden Frames vorhersagen und versuchen, 3 oder 4 von ihnen zuzuweisen, und dann die Erfassung stoppen, wenn ein Fehler auftritt. Vielleicht etwas wie dies?

const int AverageFrameSize = 10 * 1024 * 1024 // 10MB

void Image_OnAcquired(...)
{
    try
    {
        var memoryCheck = new MemoryFailPoint(AverageFrameSize * 3);
    }
    catch (InsufficientMemoryException ex)
    {
        _camera.StopAcquisition();
        StartWaitingForFreeMemory();
        return;
    }

    // if you get here, there's enough memory for at least a few
    // more frames
}

Ich bezweifle, dass das 100%ig sicher ist, aber es ist ein Anfang. Es ist auf jeden Fall zuverlässiger als der Leistungszähler aus Gründen, die in den anderen Antworten erläutert werden.

2voto

Paolo Punkte 21418

Sie können den Zähler für den freien Speicher unter Vista/7 nicht allein als Richtwert verwenden, da er nahe bei Null liegen kann. die ganze Zeit . Der Grund dafür ist die Superfetch-Funktion von Vista/7, die freien Speicher verwendet, um Dinge von der Festplatte zwischenzuspeichern, von denen sie annimmt, dass Sie sie wahrscheinlich verwenden werden.

Verlinkung: http://www.codinghorror.com/blog/2006/09/why-does-vista-use-all-my-memory.html

Darüber hinaus, wenn Sie einen 32-Bit-C#-Prozess ausführen, sind Sie ohnehin auf 2 GB Arbeitsspeicher pro Prozess beschränkt (in der Praxis eher 1,5 GB, bevor die Dinge instabil werden), so dass Sie selbst dann, wenn Ihre Box anzeigt, dass Sie jede Menge freien Arbeitsspeicher haben, eine Ausnahme wegen Speichermangels erhalten, wenn Ihr Prozess die 2-GB-Grenze erreicht.

Wie Tergiver oben anmerkt, besteht die eigentliche Lösung darin, die gesamte Datei nicht im Speicher zu halten und stattdessen Teile des Bildes je nach Bedarf in den und aus dem Speicher zu verschieben.

1voto

Darko Kenda Punkte 4661

Vielen Dank für die vielen Antworten.

Ich habe darüber nachgedacht und bin zu dem Schluss gekommen, dass es ziemlich schwierig (wenn nicht gar unmöglich) wäre, das zu tun, was ich ursprünglich wollte, nämlich irgendwie zu erkennen, wann der Anwendung der Speicher ausgeht.

Alle Antworten scheinen in dieselbe Richtung zu weisen (Daten irgendwie aus dem Speicher herauszuhalten), aber leider kann ich das nicht tun, da ich die Daten wirklich im Speicher (möglichst physisch) "brauche".

Da ich einen Kompromiss eingehen muss, habe ich beschlossen, eine Einstellung zu schaffen, mit der der Benutzer die Speicherbelegung für erfasste Daten festlegen kann. Es ist zumindest einfach zu implementieren.

0voto

Brian Rasmussen Punkte 112118

Eine OutOfMemoryException bedeutet lediglich, dass die aktuelle Speicherzuweisung nicht eingehalten werden konnte. Das bedeutet nicht unbedingt, dass dem System oder sogar dem Prozess der Speicher ausgeht. Stellen Sie sich eine Anwendung vom Typ "Hallo Welt" vor, die mit der Zuweisung eines 2 GB großen Speicherstücks beginnt. Auf einem 32-Bit-System wird dies höchstwahrscheinlich eine Ausnahme auslösen, obwohl der Prozess zu diesem Zeitpunkt noch keinen nennenswerten Speicher zugewiesen hat.

Eine häufige Ursache für OutOfMemoryExceptions ist, dass nicht genügend zusammenhängender Speicher verfügbar ist. D.h. es ist viel Speicher verfügbar, aber kein Chunk ist groß genug, um die aktuelle Anforderung zu erfüllen. Mit anderen Worten: Der Versuch, OOM durch Überwachung der Zähler für freien Speicher zu vermeiden, ist nicht wirklich machbar.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X