Heap eines Programmes auslesen
-
Hallo,
In meinem Programm erstelle ich mir eine einfach verkette Liste mit beispielsweise 1000000 Einträgen. Zur Vreinfachung hab ich mal die Daten in den einzelnen Knoten weggelassen. Wennn ich mir den theoretischen Speicherbedarf ausrechne komme ich auf: 1000001*32/8/1024/1024 = ca.3,8MB.Meine Frage lautet jetzt, gibt es eine WinAPI die mir den benötigten Heap des Programmes zurückliefert, damit ich die theoretische Aussage bestätigen kann?
lg
-
Verwende doch "GetPrcessMemoryInfo" vorher und nacher.... und das am besten in der Release-Version, sonst stimmt Deine theorie auf jeden Fall nicht... auber auch in der Release-Version musst Du noch einigen Platz für die Verwaltung dazurechnen...
-
Wenn Du für jedes Element mit 32 Byte eine eigenes new machst ist der Overhead nicht gerade klein.
Beschäftige Dich mal mit Pool-Allokatoren. Die können immensen Overhead und Allokationszeit sparen.
-
Hab das ganze jetzt mit GetPrcessMemoryInfo() ausprobiert und hab dabei den Wert WorkingSetSize mir davor und danach ausgeben lassen. Die Subtraktion dieser beiden Werte liefert mir 15,4MB genau so wie ich das im Taskmanager auch beobachtet habe. Ich erwarte mir eigentlich einen Wert von 3,9 MB.(Egal wieviel Listenelemente ich mir erzeuge der tatsächlich benötigte Speicher ist immer 4-fach so groß wie mein erwarteter Speicher). Wo ist da der Haken? Ist so viel Overhead vorhanden oder spielt mir da das Betriessystem einen Streich?
Zum Thema Pool-Allokatoren: So etwas hab ich noch nicht verwendet bzw. weiß auch nicht wirklich was das ist, aber ich denke für mein Vorhaben etwas zu aufwending da dieses Thema nur ein kleines Randgebiet ist in meiner Arbeit die ich derzeit schreibe und damit nicht so viel Zeit verschwenden will.
Ich möchte nur irgendiwe mit einer Funktion meine Ergebnis mit 3,9MB aussagekräftig bestätigt haben ohne das irgendein oberhead oder ähnliches mir reinpfuscht.
lg
-
Du kannst da nichts bestätigt bekommen. Was willst Du bestätigt bekommen? Höchstens was Dein Programm an Speicherbenötigt inkl. Overhead.
Du kannst den heap ablaufen (siehe Debug-CRT Doku) und die Blöcke manuell addieren.
Aber der Heap selbst ist eine mehrfach verkettete Liste. Mindestens 3 weitere 4-Byte Werte stecken in jeder Allokation die Du durchführst. Dann wird der Heap-Block aufeine günstige Größe gerundet.
32Byte ist klein, deshalb fällt der Overhead heftig ins Gewicht.
Zu Poolallokatoren: Die MFC benutzt automatisch welche für Ihre CList Implementierung. Hier wird ein großer Block allokiert (nur einmal overhead) und aus diesem gleich große Stücke entnommen. Die Freiblock-Verwaltung istmeistens eine einfache verkette Liste. Der Overheadbei kleinen Elementen wird drastisch verringert.
-
ok dann formulier ich meine Frage weiter:
ich hab hier eine einfach und doppelt verkettete Liste für 32-Bit und 64-Bit mit jeweils 1000000 Einträgen (ohne Daten nur pointer):Ergebnis des Speicherverbrauchs sieht folgerndermaßen aus:
32-Bit 64-Bit
einfache verkettete Liste: 16MB 16MBdoppelt verkettete Liste: 16MB 32MB
von der theorie her sollte eigentlich folgendes herauskommen:
32-Bit 64-Bit
einfache verkettete Liste: 4MB 8MBdoppelt verkettete Liste: 8MB 16MB
Wie kommen jetzt die echten Werte zustande? Der Overhead sollte ja eigentlich immer gleich bleiben meiner meinung nach.
-
Du musst den Wert "PrivateBytes" verwenden!!! Das WOrkingSet ist etwas ganz anderes...
-
Falls du C++ programmierst, Was spricht dagegen einfach eine std::list zu nehmen und diese mit 1000 * 1000 Elementen zu initialisieren?
-
Icematix schrieb:
Falls du C++ programmierst, Was spricht dagegen einfach eine std::list zu nehmen und diese mit 1000 * 1000 Elementen zu initialisieren?
Das nützt genausowenig. Die Anzahl der Allokationen sinkt dadurch gar nicht.
-
Hab mir jetzt die PrivateBytes anzeigen lassen.
Dabei komme ich auch ebenfalls auf die 16 MB.
PrivateBytes umfasst den ganzen allokierten Speicherbereich eines Prozesses, also Stack und Heap?@Martin Richter
Kannst du mir das nocheinmal genauer erklären warum ich bei einer selber implementierten Liste mehr Overhead bekomme, muss das nämlich dokumentieren das das so ist?Wenn ich mir den Speicherbereich eines Array ausgeben lasse komme ich auf meine Erwarteten werte. Warum entsteht hier kein overhead? Weil ich hier gleich einen größeren Speicherbereich allokiere und nicht nur einen Knoten?
int **vpNumber = new int*[CNT]; for(int i=0;i<CNT;i++){ vpNumber[i] = 0; }
-
Jede Allokation benötigt einen Overhead an Daten in denenen die Verwaltungsinfos des Heaps abgelegt werden.
Deshlab hast Du bei einem Block mit 1.000.000 Ints nur einmal eine Veraltungsinfo und 4.000.000 Bytes Datenbereich (sagen wir mal 3 weitere Zeiger = 12Bytes).
Bei 1.000.000 Allokationen von einem int hast Du auch 1.000.000 mal Verwaltungsinfos. mach Daten+Verwaltungsinfos = 16Bytes). == 16.000.000 Mio.Bytes an Daten wenn es gut geht und der Overhead nicht größer ist.Noch schlimmer ist es mit dem Laufzeitverhalten:
Einmal 4Mio allokieren ist nett, 1Mio mal 4 Bytes allokieren ist grober Unfug...