Speicherallocation
-
Hallo,
ich habe eine Frage zum Auslesen, wieviel Arbeitsspeicher für einen Process noch zur Verfügung steht.
Kurz zum Hintergrund: Ich schreibe ein Programm im Bereich Bildverarbeitung und 3D. Ich habe riesige Bildserien, die ich in Volumendaten umwandel und dann weiterverarbeite. Ich arbeite mit einigen OpenSource libs wie z.B. VTK.Für ein Volumen wird ein char -array angelegt und allociert. Die Allocation findet leider Gottes mit malloc() innerhalb der opensource lib statt und ich kann es nicht so ohne weiteres abändern. Auch das Fehlerabfangen ist nicht so dolle, deshalb stürzt mein Programm bei großen bildserien einfach ab, weil malloc das array allocieren kann. Das will ich abfangen und denke es muss einen Weg geben, im vorfeld zu fragen, ob noch genug Speicher zur Verfügung steht.
Wenn nicht genügend Speicher mehr zur Verfügung steht habe ich die Möglichkeit die Bilddaten um einen Faktor zu reduzieren(resample). Diesen Faktor will ich so optimal wie möglich halten. Ein Volumenarray kann Größen bis über 500mb erreichen und ich habe die Möglichkeit mehrere Volumen zu laden.
Ich habe schon einiges ausprobiert und kann mit GlobalMemoryStatus() und GetProcessMemoryInfo() alle Infos zum Process und auch zur globalen Speichersituation abfragen, wie auch beim Taskmanager od. PrecessExplorer. Leider hilft mir das nicht so viel, da malloc immer einen zusammenhängenden Speicherbereich allociert. Da der Speicher ja meist etwas fragmentiert ist gibt malloc schon recht früh auf, obwohl noch genug freier Speicher vorhanden wäre.Daher meine Frage: Gibt es eine Möglichkeit zu ermitteln wie groß der größte zusammenhängende Speicherbereich ist, den ich mit malloc allocieren kann?
Vielen Dank im voraus!
Andi
-
der Andiamo schrieb:
Hallo,
ich habe eine Frage zum Auslesen, wieviel Arbeitsspeicher für einen Process noch zur Verfügung steht.
Kurz zum Hintergrund: Ich schreibe ein Programm im Bereich Bildverarbeitung und 3D. Ich habe riesige Bildserien, die ich in Volumendaten umwandel und dann weiterverarbeite. Ich arbeite mit einigen OpenSource libs wie z.B. VTK.
Für ein Volumen wird ein char -array angelegt und allociert. Die Allocation findet leider Gottes mit malloc() innerhalb der opensource lib statt und ich kann es nicht so ohne weiteres abändern. Auch das Fehlerabfangen ist nicht so dolle, deshalb stürzt mein Programm bei großen bildserien einfach ab, weil malloc das array allocieren kann. Das will ich abfangen und denke es muss einen Weg geben, im vorfeld zu fragen, ob noch genug Speicher zur Verfügung steht.
Wenn nicht genügend Speicher mehr zur Verfügung steht habe ich die Möglichkeit die Bilddaten um einen Faktor zu reduzieren(resample). Diesen Faktor will ich so optimal wie möglich halten. Ein Volumenarray kann Größen bis über 500mb erreichen und ich habe die Möglichkeit mehrere Volumen zu laden.
Ich habe schon einiges ausprobiert und kann mit GlobalMemoryStatus() und GetProcessMemoryInfo() alle Infos zum Process und auch zur globalen Speichersituation abfragen, wie auch beim Taskmanager od. PrecessExplorer. Leider hilft mir das nicht so viel, da malloc immer einen zusammenhängenden Speicherbereich allociert. Da der Speicher ja meist etwas fragmentiert ist gibt malloc schon recht früh auf, obwohl noch genug freier Speicher vorhanden wäre.Daher meine Frage: Gibt es eine Möglichkeit zu ermitteln wie groß der größte zusammenhängende Speicherbereich ist, den ich mit malloc allocieren kann?
Vielen Dank im voraus!
AndiDas ist ja schlimm. Process statt Prozess?
In welches Forum willst Du verschoben werden?
-
Ich habe gerade davor einen Text auf engl. verfasst, da war das mit dem process noch so im Hirn, sorry.
Verschieb den Thread wohin Du willst. Hauptsache, es liest jemand, der meine Frage beantworten kann
Gruß Andi
-
der Andiamo schrieb:
Verschieb den Thread wohin Du willst.
Also den Papierkorb. Nee, erst das nächste mal. Diesmal suche ich es noch raus.
-
Dieser Thread wurde von Moderator/in volkard aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Reicht es nicht wenn genug Speicher da ist?
bool testIfThereIsEnoughMemory(size_t size){ void *p = malloc(size); free(p); return p?true:false; }Musst nur aufpassen dass dir das der Compiler nicht wegoptimiert.
Edit: Wenn du es in eine Schleife packst solltest du hinkriegen was du eigentlich wolltest.
size_t size; for (size = 1024; testIfThereIsEnoughMemory(size); size*=2); printf("Es können höchstens zwischen %d und %d Bytes Speicher reserviert werden\n", size_t==1024?0:size_t/2, size_t);
-
Besser wäre:
http://blog.kalmbachnet.de/?postid=9Sonst fragmentierst Du den Speicher mit Deiner "Schleife"...
-
Hmm, da sehe ich nicht durch.
Vielleicht könntest du die Schleife rückwärts durchlaufen, also mit dem größten Anfangen und bei jedem malloc-Fail den Speicher kleiner machen.
Und wenn du Zweierpotenzen benutzt sollte da auch nichts fragmentieren, weil du einen einzigen riesigen Block holst und den wieder freigibst.Du kannst es auch richtig übertreiben und malloc selber schreiben und dann eine Zusatzfunktion void memdefrag(void *[]) basteln was eine Liste mit per neuem malloc geholten Pointern übergeben kriegt die es umsortieren darf und das Array mit den neuen Pointern füllt. Wäre allerdings reichlich langsam.
Ich habe auch nichts fertiges in der Richtung gefunden, alles was man zu "virtual memory defrag" findet ist ein Defragmentieren der Pagefiles.
-
Moin,
vielen Dank für die Antworten. Ich hab mal beim oben genannten Link vorbeigeschaut und es klingt schon sehr nach dem was ich suche. Vielen Dank dafür.
Es gibt also zwei Varianten das Problem zu lösen. Die eine ist zu versuchen immer kleiner werdende Arrays zu allocieren und die zweite ist den gesamten Speicher zu analysieren und und den größten zusammenhängenden Speicherbereich zu suchen. Dafür würde mir im beispielcode die Funktion
SIZE_T GetLargestFreeMemRegion(LPVOID *lpBaseAddr, bool showMemInfo) sehr helfen. Mal sehen wie schnell die ist.Also nochmals danke
Andi