Optimieren der Speichernutzung Ihres Delphi-Programms

Beim Schreiben von Anwendungen mit langer Laufzeit werden die Programme, die den größten Teil des Tages verbringen, auf die Taskleiste oder minimiert System Traykann es wichtig werden, das Programm nicht mit der Speichernutzung "weglaufen" zu lassen.

Die beiden Spalten ganz rechts geben die CPU-Auslastung (Zeit) und die Speichernutzung an. Wenn ein Prozess einen dieser Punkte stark beeinträchtigt, wird Ihr System langsamer.

Die Art von Dingen, die sich häufig auf die CPU-Auslastung auswirken, ist ein Programm, das sich in einer Schleife befindet (fragen Sie jeden Programmierer, der vergessen hat, eine "read next" -Anweisung in eine Dateiverarbeitungsschleife einzufügen). Diese Art von Problemen lässt sich normalerweise leicht beheben.

Die Speichernutzung ist dagegen nicht immer offensichtlich und muss mehr als korrigiert verwaltet werden. Angenommen, ein Capture-Programm wird ausgeführt.

Dieses Programm wird den ganzen Tag über verwendet, möglicherweise für die telefonische Erfassung an einem Helpdesk oder aus einem anderen Grund. Es ist einfach nicht sinnvoll, es alle zwanzig Minuten herunterzufahren und dann erneut zu starten. Es wird den ganzen Tag über verwendet, allerdings in seltenen Abständen.

instagram viewer

Wenn dieses Programm auf einer starken internen Verarbeitung beruht oder viele Grafiken auf seinen Formularen hat, ist es früher oder später Speichernutzung wird wachsen, weniger Speicher für andere häufigere Prozesse übrig lassen, die Paging-Aktivität beschleunigen und letztendlich den Computer verlangsamen.

Angenommen, Sie entwerfen ein Programm mit dem Hauptformular und zwei zusätzlichen (modalen) Formularen. Abhängig von Ihrer Delphi-Version fügt Delphi die Formulare normalerweise in das ein Projekteinheit (DPR-Datei) und enthält eine Zeile zum Erstellen aller Formulare beim Start der Anwendung (Anwendung. CreateForm (...)

Die in der Projekteinheit enthaltenen Linien stammen von Delphi und eignen sich hervorragend für Personen, die mit Delphi nicht vertraut sind oder es gerade erst verwenden. Es ist bequem und hilfreich. Dies bedeutet auch, dass ALLE Formulare beim Start des Programms erstellt werden und NICHT, wenn sie benötigt werden.

Je nachdem, worum es in Ihrem Projekt geht und welche Funktionen Sie in einem Formular implementiert haben, kann dies viel Speicherplatz beanspruchen Formulare (oder allgemein: Objekte) sollten nur bei Bedarf erstellt und zerstört (freigegeben) werden, sobald sie nicht mehr vorhanden sind notwendig.

Sowohl "DialogForm" als auch "OccasionalForm" müssen aus der Liste der "automatisch erstellten Formulare" entfernt und in die Liste "Verfügbare Formulare" verschoben werden.

Bitte beachten Sie, dass die hier beschriebene Strategie auf der Annahme basiert, dass es sich bei dem betreffenden Programm um ein Echtzeitprogramm vom Typ „Capture“ handelt. Es kann jedoch leicht für Chargenprozesse angepasst werden.

Delphi hat versucht, dies zu minimieren und verfügt über eine eigene Speicherverwaltungsarchitektur, die viel kleinere Blöcke verwendet, dies ist jedoch der Fall In der Windows-Umgebung praktisch unbrauchbar, da die Speicherzuweisung letztendlich beim Betriebssystem liegt.

Sobald Windows einem Prozess einen Speicherblock zugewiesen hat und dieser Prozess 99,9% des Speichers freigibt, Windows erkennt weiterhin, dass der gesamte Block verwendet wird, auch wenn tatsächlich nur ein Byte des Blocks vorhanden ist benutzt. Die gute Nachricht ist, dass Windows einen Mechanismus zur Behebung dieses Problems bietet. Die Shell bietet uns eine API namens SetProcessWorkingSetSize. Hier ist die Unterschrift:

Per Definition legt die Funktion SetProcessWorkingSetSize die minimalen und maximalen Arbeitssatzgrößen für den angegebenen Prozess fest.

Diese API soll eine niedrige Einstellung der minimalen und maximalen Speichergrenzen für den Speicherbedarf des Prozesses ermöglichen. Es ist jedoch eine kleine Eigenart eingebaut, die am glücklichsten ist.

Wenn sowohl der Minimal- als auch der Maximalwert auf $ FFFFFFFF festgelegt sind, schneidet die API die eingestellte Größe vorübergehend auf 0, tauscht sie aus dem Speicher aus und sofort wie sie ist Wenn es zurück in den Arbeitsspeicher springt, wird ihm nur die minimale Menge an Speicher zugewiesen (dies alles geschieht innerhalb von ein paar Nanosekunden, also sollte es für den Benutzer so sein unmerklich).

Ein Aufruf dieser API erfolgt nur in bestimmten Intervallen - nicht kontinuierlich, daher sollte die Leistung überhaupt nicht beeinträchtigt werden.

Überprüfen Sie nun regelmäßig die Anzahl der letzten Ticks gegen "Jetzt". Wenn der Unterschied zwischen beiden größer ist als der Zeitraum, der als sichere Leerlaufzeit angesehen wird, kürzen Sie den Speicher.

Entscheiden Sie nun, nach welcher Zeit das Programm als inaktiv eingestuft wird. In meinem Fall haben wir uns für zwei Minuten entschieden, aber Sie können je nach den Umständen einen beliebigen Zeitraum auswählen.

Die Anpassung dieser Methode an lange Verarbeitungszeiten oder Batch-Prozesse ist recht einfach. Normalerweise haben Sie eine gute Vorstellung davon, wo ein langer Prozess beginnt (z. B. Beginn einer Schleife, die Millionen von Datenbankeinträgen durchliest) und wo er endet (Ende der Datenbankleseschleife).

Deaktivieren Sie einfach Ihren Timer zu Beginn des Prozesses und aktivieren Sie ihn am Ende des Prozesses erneut.