Frage

Ich habe in meinem Programm vor kurzem ein seltsames Verhalten gesehen. Nach dem Erstellen dann große Mengen von Objekten (500 MB RAM), um sie Loslassen der Speicherbedarf des Programms nicht zurück auf seine ursprüngliche Größe. Es zeigt noch eine Grundfläche von 160 MB (Privater Arbeitssatz).

Ein normales Verhalten?

Borland Memory-Manager verhält sich nicht wie diese, so dass, wenn möglich, bitte bestätigen (oder Gebrechliche) das ein normales Verhalten für FastMM ist: Wenn Sie ein praktisches Programm, in dem Sie ein ziemlich komplexes MDI Kind erstellen (mit mehreren Kontrollen / Objekten ), können Sie in einer Schleife 250 Instanzen dieses MDI Kind im Speicher (zur gleichen Zeit), dann lassen Sie sie alle und prüfen Sie den Speicherbedarf erstellen. Bitte stellen Sie sicher, dass Sie mindestens 200-300MB oder RAM mit dem MDI Childs verbrauchen.

Besonders 7 diejenigen, die noch mit Delphi die Differenz durch temporäre Sperrung FastMM sehen können.

Danke


Wenn jemand interessiert ist, vor allem, wenn Sie einen Beweis wollen dies ist kein Speicherleck (ich hoffe, es ist kein mem Leck in meinem Code - das ist auch einer der Punkte dieser Stelle ist: um zu überprüfen, ob es mein ist Fehler), hier sind die ursprünglichen Diskussionen:

Mein Programm veröffentlicht nie die Erinnerung zurück. Warum?
Wie die Speicher-Manager davon zu überzeugen, nicht verwendete Speicher freizugeben

War es hilfreich?

Lösung 5

GELÖST

, um zu bestätigen, dass dieses Verhalten durch FastMM erzeugt wird (wie von Barry Kelly vorgeschlagen) habe ich ein zweites Programm, das eine Menge RAM zugewiesen. Sobald Windows-RAM, Nutzung mein Programm lief Speicher auf den ursprünglichen Wert zurückgeführt.

Problem gelöst. Besonderer Dank geht an Barry Kelly, die einzige Person, die spitze der realen „Problem“.

Andere Tipps

IIRC, die Delphi-Speicher-Manager nicht sofort free'd Speicher an das Betriebssystem zurück.

Der Speicher wird in Blöcken von kleinen, mittleren und großen Größen, genannt Blöcke zugeordnet. Diese Blöcke werden für eine Weile gehalten, nachdem ihr Inhalt angeordnet haben sie readyly zur Verfügung zu haben, wenn eine andere Zuordnung danach angefordert wird.

Dies begrenzt die Menge des Systems für alle aufeinanderfolgenden Zuordnung von mehreren Objekten erforderlich Anrufe und Heap-Fragmentierung hilft zu vermeiden.

Infirming: Delphi 2007, Standard-Speicher-Manager (sollte FastMM Variation sein). Mehrere Tests auf schwere Gegenstände:

  1. Initial Speicher 2MB, Spitzenwertspeicher 30 MB, final Speicher 4MB.
  2. Initial Speicher 2MB, Spitzenwertspeicher 1 GB, Endspeicher 5.5Mb.

Lieber Altar, ich bin, wie vom Punkt geblendet Sie in Ihren Vermutungen sind und wie Sie hören nicht auf, was die Leute gesagt, viele Male vor.

Lassen Sie uns Satz einige Dinge gerade. Speicherverwaltung 101 Bitte lesen Sie gründlich.

Wenn Sie Speicher in Delphi zuweisen, gibt es zwei Speicher beteiligten Manager.

Systemspeicher-Manager

Das erste ist ein Systemspeicher-Manager. Dieser ist in Windows integriert und es gibt Speicher in 4kb Größe Seiten.

Aber es muss nicht immer geben Sie Speicher im RAM (oder physischen Speicher). Ihre Daten können auf der Festplatte gehalten werden, und jedes Mal, wenn Sie es brauchen für den Zugriff lesen zurück. Das ist furchtbar langsam.

Mit anderen Worten, stellen Sie sich 512 MB physischen Speicher haben. Sie können zwei Programme laufen, die jeweils anfordernden 1 GB Arbeitsspeicher. Was bedeutet O tun?

Es gewährt beide Anfragen. Beide Anwendungen erhalten 1 GB Arbeitsspeicher je. Beide denken den ganzen Speicher „im Speicher“ ist. Aber in der Tat kann nur 512Mb im RAM gehalten werden. Der Rest wird in der Auslagerungsdatei gespeichert, obwohl die App das nicht weiß. Es funktioniert nur langsam.

Arbeitssatzgröße

Nun, was ist eine „Arbeitssatzgröße“ Sie messen?

Es ist der Teil des zugeordneten Speichers, im RAM gehalten wird.

Wenn Sie eine Anwendung haben, die 1 GB Speicher reserviert, und Sie haben nur 512 MB RAM, dann wird es funktioniert Satzgröße 512 MB sein. Obwohl es "uses" 1 GB Speicher!

Wenn Sie eine andere Anwendung ausführen, die Speicher benötigt, O wird automatisch einige RAM frei von selten genutzten Blöcke von „Speichern“ auf die Festplatte zu bewegen.

wird Ihre virtuelle Speicherzuweisung gleich bleiben, aber mehr Seiten auf der Festplatte und weniger in RAM sein. Arbeitssatzgröße abnehmen.

Von diesem sollte man von diesem Punkt verstanden hat, dass es sinnlos ist, die Arbeitssatzgröße, um zu versuchen und zu minimieren. Sie sind zu erreichen nichts. Sie nicht Speicher in jedem Sinne zu befreien . Sie sind nur die Daten auf die Festplatte ausgelagert.

Aber das System tun, dass sich automatisch, wenn sie muss. Und es gibt keinen Punkt Raum im RAM machen, bis es gebraucht wird. Sie sind nur Ihre Anwendung zu verlangsamen, das ist alles.

TLDR : "Working Set-Größe" ist nicht "wie viel Speicher Anwendung verwendet". Es ist „wie viel bereit ist im Moment“. Versuchen Sie nicht, es zu minimieren, die Sie gerade machen alles noch schlimmer.

Delphi-Speicher-Manager

O gibt Ihnen die virtuellen Speicher in Seiten von 4 KB. Aber oft müssen Sie es in vielen kleineren Stücken. Zum Beispiel des Bytes 4 für Ihre ganze Zahl, oder 32 Bytes für einige Struktur. Die Lösung?

Anwendungsspeichermanager, wie FastMM oder BorlandMM oder andere.

Es hat die Aufgabe, Speicher in Seiten aus dem Betriebssystem zuzuweisen, und geben Sie kleine Stücke dieser Seiten, wenn Sie es brauchen.

Mit anderen Worten, wenn Sie für 14 Byte Speicher fragen, das ist, was passiert:

  1. Sie fragen FastMM für 14 Byte Speicher.
  2. FastMM fragt O für 1 Seite des Speichers (4096 Bytes).
  3. OS gewährt eine Seite des Speichers, es mit RAM sichern (es in der tatsächlichen RAM gespeichert ist).
  4. FastMM speichert die Seite, schneidet 14 Byte davon und gibt Ihnen.

Wenn Sie für weitere 14 Bytes fragen, FastMM schneidet nur weitere 14 Bytes von der gleichen Seite.

Was passiert, wenn Sie Speicher freigeben? Die gleiche Sache nach hinten:

  1. Sie geben 14 Bytes FastMM. Es passiert nichts.
  2. Sie geben weitere 14 Bytes. FastMM sieht, dass die 4096-Byte-Seite zugeordnet ist nun völlig ungenutzt.
  3. Deshalb gibt er die Seite, es an das System zurück.

Es ist erwähnenswert, dass FastMM kann nicht loslassen nur 14 Bytes an das System. Es verfügt über Speicher in Seiten veröffentlichen. Bis die ganze Seite frei ist, kann FastMM etwas nicht tun. Niemand kann.

So

, warum ist meine Arbeitssatzgröße so groß, obwohl ich alles freigegeben?

Zuerst Ihre Arbeitssatzgröße ist nicht das, was Sie messen werden sollen. Virtuelle Speicherverbrauch ist. Aber wenn Sie haben großeArbeitssatzgröße, wird Ihr virtueller Speicherverbrauch hoch sein.

Was ist das Problem? Sie sollen von diesem Punkt, um herauszufinden, der Lage sein.

Angenommen, Sie verteilen 1kb, dann 3kb Speicher. Wie viel virtuellen Speicher haben Sie zugewiesen? 4kb, 1 Seite.

Jetzt lassen Sie 3Kb. Wie viel virtuellen Speicher verwenden Sie jetzt? 1Kb? Nein, es ist noch 1 Seite. Sie können nicht weniger als 1 Seite aus dem System zuzuweisen. Sie sind immer noch 4096 Bytes des virtuellen Speichers verwendet wird.

Stellen Sie sich vor, wenn Sie feststellen, dass 1000 mal tun. 1kb, 3 kb, 1 kb, 3 kb, 1 kb, 3 kb und so weiter. Sie ordnen 1000 * 4 kb = 4 mb so, und dann freigeben Sie alle 3kb Teile. Wie viel virtuellen Speicher verwenden Sie jetzt?

Still 4 mb. Weil Sie zugeteilt 1000 Seiten auf den ersten. Von jeder Seite nahm man 1kb und 3kb Brocken. Auch wenn Sie 3kb Stücke loslassen, wird 1kb Stücke weiterhin jede einzelne Seite, um Sie in Speicher zugewiesen. Und jede Seite nimmt 4kb des virtuellen Speichers.

Speicher-Manager kann nicht auf magische Weise „bewegen“ alle Ihre 1kb Stücke zusammen. Das ist unmöglich, weil ihre virtuellen Adressen können von irgendwo im Code referenziert werden. Es ist kein Merkmal von FastMM.

Aber warum mit BorlandMM alles funktioniert besser?

Koinzidenz. Vielleicht passiert es einfach so, dass BorlandMM Sie Speicher auf eine etwas andere Art und Weise gibt, als FastMM tut. Das nächste, was Sie wissen, ändern Sie etwas in Ihrem App und BorlandMM verhält sich wie FastMM tat. Es ist unmöglich, für einen Speichermanager vollständig diesen Effekt zu verhindern, die so genannte Speicherfragmentierung.

Also, was soll ich tun?

Kurze Antwort ist, nicht viel, bis diese stört.

Sie sehen, mit modernen Betriebssystemen, ich bin nicht wirklich jedermann RAM zu essen. Per oben, O tauschen Sie Ihre Seiten automatisch aus, wenn es benötigt RAM für andere Anwendungen. Dies sollte kein Problem sein.

Und das „exzessive“ Gedächtnis nicht verloren. Obwohl Seiten zugewiesen, 3 KB jeder wird als „frei“ gekennzeichnet. Das nächste Mal Ihre App-Speicher benötigt, Speicher-Manager wird diesen Raum nutzen.

Aber wenn Sie es wirklich helfen wollen, sollten Sie Ihre Zuweisungen so reorganisieren, dass die, die Sie planen, auf Haltung zunächst getan, und die, die Sie bald nach, dass alle zugewiesenen wird freigeben werden.

Wie diese: 1 kb, 1 kb, 1 kb, ..., 3 kb, 3 kb, 3 kb ...

Wenn Sie nun all 3 kb Stücke freigeben, Ihr virtueller Speicherverbrauch deutlich sinken wird.

Dies ist nicht immer möglich. Wenn es nicht möglich ist, dann tut einfach nichts. Es ist mehr oder weniger in Ordnung, wie es ist.

Und P. S.

Sie sollten nicht mehr als 500 Formen an erster Stelle werden die Zuteilung. Dies ist eindeutig kein Weg zu gehen. Dieses Problem beheben, und Sie werden nicht einmal eine Notwendigkeit, um die Speicherzuordnung zu denken und zu veröffentlichen.

Ich hoffe, das klärt die Dinge, weil vier Beiträge zum gleichen Thema, ehrlich gesagt, ein bisschen zu viel.

Was sind die heapmanager Statistiken (GetHeapStatus) an dem Punkt, dass 160MB noch zugeordnet ist?

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