Frage

Ich verwende VMMap von SysInternals an Speichern von meiner Win32 C ++ Prozess auf WinXP zugewiesen zu sehen, und ich sehe eine Reihe von Zuweisungen, wo Teile des zugewiesenen Speichers reserviert sind, aber nicht verpflichtet. Soweit ich das beurteilen kann, aus meiner Lektüre und Prüfung, die alle den gemeinsamen Speicher Verteilern (zum Beispiel malloc, neu, LocalAlloc, GlobalAlloc) verwendet in einem C ++ Programm immer voll engagierte Speicherblöcke zugewiesen werden. Heaps sind ein typisches Beispiel für Code, dass Reserven Speicher, ihn aber nicht verpflichten, bis sie benötigt. Ich vermute, dass einige dieser Blöcke sind Windows / CRT Haufen, aber es scheint mehr dieser Arten von Blöcken zu sein, als ich für Haufen erwarten würde. Ich sehe in der Größenordnung von 30 dieser Blöcke in meinem Prozess, zwischen 64k und 8 MB groß, und ich weiß, dass mein Code niemals absichtlich VirtualAlloc Anrufe reserviert zuzuteilen, nicht gebundenen Speicher.

Hier sind ein paar Beispiele von VMMap: http://www.flickr. com / Fotos / 95123032 @ N00 / 5280550393 /

Was sonst würde zuweisen solche Speicherblöcke, in denen ein Großteil davon ist reserviert, aber nicht begangen hat? Wäre es sinnvoll, dass mein Prozess 30 Haufen hat? Danke.

War es hilfreich?

Lösung

Habe ich es aus - es ist der CRT-Heap, die durch Anrufe malloc zugewiesen wird. Wenn Sie einen großen Teil des Speichers zuweisen (zum Beispiel 2 MB) mit malloc, weist sie einen einzigen engagierten Speicherblock. Aber wenn Sie kleinere Stücke (etwa 177KB) zuweisen, dann wird es einen 1 MB Teil des Speichers reservieren, sondern nur begehen ungefähr das, was Sie gefragt (zum Beispiel 184kb für meine 177KB Anfrage).

Wenn Sie frei, dass kleine Klumpen, die größer 1 MB chunk nicht an das Betriebssystem zurückgegeben wird. Alles aber 4k ist nicht gebundenes, aber das volle 1 MB noch reserviert. Wenn Sie dann malloc wieder aufrufen, versucht, es zu benutzen, dass 1 MB chunk Ihre Anforderung zu erfüllen. Wenn es nicht Ihre Anfrage mit dem Speicher erfüllen kann, dass es bereits reserviert ist, wird es einen neuen Teil des Speichers zuweisen, die das Doppelte der vorherige Zuordnung ist (in meinem Fall ging es von 1 MB bis 2 MB). Ich bin mir nicht sicher, ob das Muster der Verdoppelung weiter oder nicht.

Zur Rückkehr tatsächlich Ihre freigegebenen Speicher an das Betriebssystem, können Sie _heapmin nennen. Ich würde denken, dass dies eine Zukunft große Zuteilung wahrscheinlicher macht um erfolgreich zu sein, aber es würde hängt alle auf Speicherfragmentierung, und vielleicht heapmin wird bereits aufgerufen, wenn eine Zuordnung nicht (?), Ich bin nicht sicher. Es wäre auch eine Performance-Einbußen, da heapmin den Speicher freigeben würde (die Zeit nehmen) und malloc müßte dann Neuzuweisung es vom Betriebssystem, wenn wieder benötigt. Diese Information ist für Windows / XP 32, die Leistung kann variieren.

UPDATE: In meinen Tests, tat heapmin absolut nichts. Und der malloc Haufen nur für die Blöcke verwendet, die weniger als 512 kb. Auch wenn es MBs von zusammenhängender freier Speicherplatz im malloc Haufen ist, wird es nicht für Anfragen über 512kb verwenden. In meinem Fall, das befreit, nicht verwendet, noch malloc Speicher reserviert zerkaut große Teile meines Prozesses 2 GB Adressraum, was schließlich zum Speicherzuordnungsfehler führt. Und da heapmin den Speicher nicht an das Betriebssystem zurückkehren, ich habe festgestellt, keine Lösung für dieses Problem, anders als meinen Prozess neu zu starten oder meine eigenen Speicher-Manager schreiben.

Andere Tipps

Könnten sie die DLLs in Ihren Prozess geladen werden? DLLs (und die ausführbare Datei) sind Speicher in den Prozessadressraum abgebildet. Ich glaube, dass diese zunächst nur reserviert Platz. Der Raum wird durch die Dateien gesichert selbst (zumindest anfangs) eher als die Auslagerungsdatei.

Nur der Code, der tatsächlich berührt hat wird ausgelagert. Wenn ich die Terminologie richtig verstehen, das ist, wenn es begangen wird.

Sie können dies bestätigen, indem Sie Ihre Anwendung in einem Debugger ausgeführt und Blick auf die Module, die geladen werden und den Vergleich ihrer Lage und Größe, was Sie sehen in VMMap.

Jedes Mal, wenn ein Thread in Ihrer Anwendung erstellt wird eine bestimmte (konfigurierbar) Speichermenge wird in dem Adressraum für den Call-Stack des Threads reserviert werden. Es gibt keine Notwendigkeit, alle reservierten Speicher zu begehen, es sei denn der Thread eigentlich alle, dass der Speicher brauchen wird. So wird nur ein Teil Bedürfnis verpflichtet werden.

Wenn mehr als die engagierte Speichermenge erforderlich ist, wird es möglich sein, mehr Systemspeicher zu erhalten.

Die praktische Überlegung ist, dass der reservierte Speicher eine harte Grenze für die Stack-Größe ist, den Adressraum für die Anwendung verfügbar reduziert. Indem jedoch nur einen Teil der Reserve zu begehen, wir müssen nicht die gleiche Menge an Speicher aus dem System verbrauchen bis benötigt.

Daher ist es möglich, für jeden Faden einen Teil des reservierten uncommitted Speicher zu haben. Ich bin nicht sicher, was die Seite Typ in diesen Fällen sein wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top