Ein recycling Fabrik-Muster in delphi


Die Probleme der Verwendung und Wiederverwendung von vielen unterschiedlicher Größe-Objekten in einer Anwendung können die Fragmentierung des Heap führen, die Verarbeitungsgeschwindigkeit verlangsamen können. In diesem Artikel verwendet ein Factory-Objekt zu machen und Objekte mit minimalen Fragmentierung Auswirkungen zu recyceln.
Eines der Muster in das klassische Buch 'Design Patterns; Elemente der Reusable Object-Oriented Software'ist die Factory-Methode, wobei Objekte erstellt und vor kurzem hatte ich es zu benutzen. Der Grund dafür? Ein Speicherproblem Fragmentierung in ein Simulationssystem, verwenden eine große Anzahl von Objekten zum numerischen Arrays enthalten. Gab es mehrere numerische Arraytypen, in festen Größen variierend von 1500 X 5000 x 1-10 Nummern entweder ganze Zahlen oder Doppelzimmer. Diese wurden in einer Simulation einer finanzielle Berechnung über einen Zeitraum von zwei Jahren erstellen Daten auf jedem 472 simulierten Tagen aus historischen Daten eingesetzt. An jedem Tag war Daten aus einer Datenbank gelesen, verarbeitet, dann heraus gespeichert.
Trotz umfangreichen Leck überprüfen, würde die Software nur für eine Reihe von simulierten Tagen vor dem Essen bis die Windows-Auslagerungsdatei ausgeführt. Memory-Leaks wurden sorgfältig aufgespürt und eliminiert, aber mein Haar war immer noch in Gefahr. Die app würde nicht länger als ca. 30 simulierten Tage bevor es mehr als die Hälfte der NT Paging Datei - dies auf einem 512 Mb-Ram-System begangen hatte laufen! Schließen Sie Untersuchung ergab, dass an jedem Tag lief es, der reservierte Speicher von 5M auf ca. 80Mb vergrößert wurde, dann zurück zu ca. 5 M wieder zu verkleinern. Auf den ersten Blick zeigte kein Problem mit 512 Mb zu spielen mit, aber gerade der Win NT-Taskmanager eine zunehmende Menge an Arbeitsspeicher begangen.
FRAGMENTIERUNG
Das Problem war einfach, es war Heapfragmentierung Schuld. Dies passiert, wenn viele verschiedene Objekte erstellt und dann immer wieder zerstört. Jedes Objekt erstellt wird, verbraucht es Speicher aus dem Heap. Wenn Objekte wurden erstellt und dann in umgekehrter Reihenfolge zerstört würde nicht es wohl passieren, wie alle freigegebene Speicher in einem großen Block zusammengeführt werden könnten. Aber in jedem System mit einer großen Anzahl von Objekten die Reihenfolge der Schöpfung und Zerstörung werden nie symmetrisch - meine app kann leicht bis zu 50.000 Objekte im Speicher haben, zur gleichen Zeit. Wenn ein Objekt zerstört wird, wird ein Zeiger auf den freigegebenen Speicher-Block frei-Sperrliste hinzugefügt.
Wenn andere Anforderungen für Arbeitsspeicher vorgenommen werden, versucht Windows, diese Anforderungen aus der freigegebenen Liste zuerst zuweisen. Fragmentierung passiert wo ein großer Block wie 1Mb wurde angefordert und später freigegeben, gefolgt von einer Anforderung für einen kleineren Block. Dies ist der erste Block über die kostenlose Liste entnommen, die der 1 Mb, kann gut sein, der nur 900 Kb frei lässt. Dann eine weitere Anforderung für einen großen Block 1Mb kommt, es kann nicht aus der Freiliste zufrieden sein und es also aus dem Heap stammt. Wenn der Zyklus der Schöpfung/Zerstörung oft genug die große Blöcke auf dem Heap geschieht sind in kleinere Stücke gehackt; der physische Ram ist erschöpft und mit virtueller Ram ersetzt. Windows-Heap-Speichermanagement (und Delphi) ist ziemlich clever-It braucht viel um es zu fragmentieren. Aber unter dem unerbittlichen Druck einer großen Anzahl von Objekten erstellt und zerstört werden, der Speicher-Manager wird allmählich in der Höhle.
Wenn Windows läuft aus freien Ram, es beginnt Seiten RAM Disk und Leistung auszulagern, nimmt einen Sturzflug. Ihre app könnte glücklich zusammen bei 100 % CPU im Galopp werden bis zu swappen beginnt. Es wird dann ein Trauermarsch Crawlen entlang vielleicht 7-10 % der CPU, wobei immer ausgeführt. Katastrophe!
Microsoft habe viel Mühe, die den Speicher-Manager so effizient wie möglich zu machen. Unter NT gibt es zum Beispiel ein zweistufigen Prozess der reservieren und Speicher zu begehen. Wenn Ihre app 100 Mb erfordert, ist es vorbehalten, wenn die app geladen wird. Aber nur, wenn der Speicher zugegriffen wird sind die Reserve-Seiten begangen. Wenn Sie mehr als Sie jemals möglicherweise müssen über dieses und andere Themen kennen lernen möchten, ich empfehle das Buch Inside NT, herausgegeben von Microsoft Press, sondern erhalten die David Solomon Fassung der späteren Ausgabe nicht Helen Custer Erstausgabe.
FABRIK-MUSTER
Also ich mit ihnen, nicht zersplittert derart viele Objekte zu schaffen brauchte, sie wegzuwerfen und dann tut es wieder ohne Windows virtuellen Speicher zur Neige. Das Muster-Buch vor kurzem gelesen, dachte ich, warum keine Fabrik, d. h. ein Factory-Objekt, die Objekte einer Klasse erstellt. Ich ging besser und machte es umweltfreundlich, so wird es, alle hergestellten Objekte statt vernichten und die zugehörigen zersplittert problemlos zu recyceln. Das Tüpfelchen auf dem i war das Werk in der Lage, seine Kapazitäten ohne Verlust der Zugriffsgeschwindigkeit ausbauen lassen.
Anstatt eine Factory-Klasse für alle Klassentypen haben, habe ich den einfacheren Ansatz des Führens der Object-Klasse in die Fabrik als eine Fabrik-Erstellungsparameter. Wenn die Fabrik erstellt wird, geben Sie sowohl Klasse von Objekten, die sie vornehmen kann und die anfängliche Speicherkapazität der Fabrik. Diese Größe kann geändert werden, nach oben durch Aufrufen der GrowFactory-Methode. Ich schlage vor, dass Sie dies nur in Ausnahmefällen (!) Umständen aufrufen.
Der Link zu der Fabrik der einzelnen Objekte ist erforderlich, damit alle 'Fabrik hergestellt-Objekte' (FMO) von einer TFactoryObject Klasse statt Tobject absteigen müssen. Dies fügt einen Fabrik-Verweis die 'gestempelt ist' auf alle FMO, so dass das Objekt, welche Fabrik weiß verwenden, um selbst zu recyceln.
Anstatt ein Objekt Ihrer app Anfragen einer werkseitig geeignet durch Aufrufen der RequestObj-Methode, die ein Tclass-Objekt zurückgibt zurück und Sie ihn in die richtige Klasse mit 'als' umwandeln. Schließlich wenn Sie fertig sind mit dem Objekt rufen Sie nur die RecycleSelf-Methode. Keine Erstellung oder Zerstörung mit Ausnahme der Fabriken selbst.
WIE ES FUNKTIONIERT

Wenn die Fabrik erstellt wird, werden alle Objekte physikalisch in einen zusammenhängenden Block RAM erstellt. Ein Tlist (Fblocklist)-Objekt enthält die Adresse eines jeden dieser Blöcke. Jedes Mal, wenn Sie das Werk wachsen ein neuer Block erstellt und in diese Liste aufgenommen. Die Methode AddObjects erstellt die angegebene Anzahl von Objekten mit dem Ram aus dem Block. Wenn Sie schreiben sein Code wie diesen bewusst, dass gerade dabei eine tobject(address) nicht ausreicht um das Objekt zu erstellen. Sie müssen immer ObjectClass.InitInstance(address) um es in eine 'richtige' Objekt transformieren aufrufen. InitInstance löscht alles auf NULL, NULL etc., aber noch wichtiger ist es die VMT richtet.
Das Werk enthält auch eine andere Tlist (Ffreelist), die die Adresse alle nicht verwendeten Objekts enthält.
Alle Esel Arbeit der Füllung der Fabrik in die private Methode AddObjects unternommen. Für jedes Objekt im Block erstellt konvertiert diese in ein Objekt mit FactoryObject als die Klasse des Objekts erstellt die Zeiger Ptr. Dies muss immer ein Nachkomme des TfactoryObject sein. Obj hält den Objektverweis und verbindet die Fabrik hergestellten Objekt. PTR ist dann inkrementiert, um zum nächsten Objekt im Block zu zeigen, indem Sie hinzufügen Fsize.
Zum Abrufen eines Objekts sind Sie Code ruft Request_Obj, erscheint der Hinweis am Ende der Ffreelist und als das erste angeforderte Objekt zurückgibt. Recycling ist das Gegenteil; Es legt den recycelten Objektverweis auf das Ende des Ffreelist. Eine Sache zu beachten. Wenn eine Fabrik hergestellt Objekt verwendet wird, hat die Fabrik jeder Verweis darauf, keine, obwohl der vom Objekt belegte Speicher innerhalb der Fabrik enthalten ist!
ERSTELLEN UND ZERSTÖREN ERSETZEN
Die Fabrik müssen Sie hergestellten Objekte etwas anders von 'normal' verwenden. Sie nicht mehr erstellen oder explizit zu befreien, statt Sie nur die relevante Fabrik für das Objekt anfordern. Es sei denn, die Fabrik leer ist funktioniert das immer. Du musst die Initialisierung Code im Konstruktor und Terminierungscode in den Destruktor-Routinen ändern. Es gibt zwei Ansätze.
1) Wenn das Objekt verfügt über eine einfache Erstellen Konstruktor ohne Parameter, können Sie benennen sie Prozedur init; außer Kraft setzen und entfernen Sie alle geerbten erstellen-Aufrufe. Die Fabrik wird immer eine Init-Methode, wenn ein Objekt angefordert wird. Standardmäßig tut dies nichts, aber Sie können dies überschreiben, so dass Ihre Init automatisch auf jedes Objekt angefordert ab Werk aufgerufen wird.
2) Wenn Ihre ursprüngliche erstellen Parameter hat, benennen Sie sie um so etwas wie Initialise und entfernen Sie geerbte etc. Aufrufe. Nach dem Objekt ist angeforderte Aufruf der Routine Initialise, zB MyRoutine.Initialise(...)
Wenn das Objekt Destruktorcode, in Verfahren, die getan; umbenennen überschreiben Sie, sodass sie automatisch aufgerufen wird, wenn das Objekt wiederverwendet wird. Init und fertig sind ähnlich zu erstellen/zu zerstören, aber ohne das Gepäck der Mechanismus der Konstruktion oder Zerstörung.
Als einen kleinen Exkurs Wissens meines gibt es Argumente in der Delphi-Welt dafür auf einen Teil von Arbeitsplätzen oder Teil einer zweiteiligen ist, wo der Konstruktor über Parameter verfügt und das Objekt vollständig richtet. In der zweiteiligen Ansatz erstellt der Konstruktor nur ein leeres Objekt, das dann durch eine neuere Methode initialisiert wird. Der Factory-Ansatz denke ich ist fest im zweiteiligen Lager...
Wenn die Fabrik zerstört wird, werden die zugewiesenen Speicherblöcke freigegeben. Vor diesem überprüft das Werk, dass die Anzahl der Objekte in der Freelist die Kapazität entspricht. Wenn Sie vergessen haben, Ihre verbleibenden Objekte wiederverwenden, wird eine Ausnahme ausgelöst.
VERGLEICH-PROGRAMM
Dies zeigt die Vorteile von Fabriken... Bei der Arbeit meine app hatte viele verschiedene Größen der Objekte in unterschiedlichen Mengen, aber ein 15.000 Linie-Programm wäre nicht gerade veröffentlichungsreife. Nach einer Weile des Ausprobierens kam ich mit einem kurzen Programm, das Fragmentierung zeigen kann. Dies hängt jedoch die Größe der verschiedenen Objekte, wie viele es sind, freier Arbeitsspeicher und für wie lange er läuft. Auch scheint Fragmentierung, schneller auf NT4. 0 als 98, was darauf hindeutet, dass vielleicht 98 hat eine bessere Speicherverwaltung auftreten. Beim Ausführen wird erstellt und eine große Anzahl von Objekten immer wieder für die angegebene Anzahl von Tagen zerstört. Es tut auch genau das gleiche, die mithilfe einer Factory. Jeden Tag ist so terminiert, und beide Male geplant verwendend Tchart.
Ich habe drei Typen von Objekten, von tTestobj die von Tfactoryobject senkt sich alle abstammen. Kleine Objekte sind 2 K groß, Medium sind 40K und groß sind 800K, aber diese Größen werden durch Konstanten definiert und können leicht geändert. Das Demoprogramm weist 100Mb für die normale Objekte und eine weitere 100Mb für die Fabrik. Beide enthalten die gleiche Anzahl von Objekten-gleichmäßig aufgeteilt nach Größe zwischen den drei Objekttypen, so gibt es 17406 kleine Objekte, 873 Medium und große 43. In der Objekt-Erstellungsverfahren TimeOneDay sind diese nach dem Zufallsprinzip erstellt und zur Liste hinzugefügt. Am Ende des Tages werden sie freigegeben werden und der Vorgang wiederholt am nächsten Tag.
Das gleiche geschieht mit drei Fabriken mit alle hergestellten Objekte, die eine Factorydata-Liste hinzugefügt. Auf einer P2-400 mit 256Mb läuft für 100 Tage gab es ein moderaten Anstieg der die Zeit für die Fabrik und die normalen Objekterstellung. Kommentieren Sie die normale Einrichtung bestätigt, dass dieser Verdacht-der Anstieg war viel weniger über 1000 täglich laufen sowohl Normal als auch Werk mit Fabriken gegen 100 Tage. Ich vermutete, dass dies durch erhöhte Seite aufgrund von Fragmentierung Auswirkungen auf beide Prozesse Auslagern verursacht wurde. Einige andere Kombinationen von Größen und Anzahl der Objekte unter Windows 98 zeigte keine Fragmentierung
Ich dies implementiert, ursprünglich mit einem Tlist für Testdata und Factorydata und später geändert, als ich merkte, dass wiederholt hinzufügen und Freigeben von 18000 Zeiger auch Heapfragmentierung hinzugefügt wurde. Ich bin nicht dafür Notwasserung Tstringlists vollständig in Ihrem Code-sie sind sehr nützlich, (wie Tlists), aber haben Sie eine große Anzahl von Elementen zu manipulieren, es wäre besser, eigene Liste Strukturen zu verwenden. Möchten Sie für diesen Zweck, die wahrscheinlich besser, die Struktur mit Null-Zeigern, vollständig auszufüllen, damit das zählen Tlist oder Tstringlist verwenden = Kapazität und eine ganze Zahl für den Index des letzten Pointer verwenden.
Diese app auch bestätigt, dass der Fabrik-Code ist sehr schnell bei der Zuweisung und löschen-in der Regel 30 ms für 18000 Objekte anstelle der 870 ms, dass normale anlegen/löschen nahm.
------------------------------------------------
Tgis Artikel erschien ursprünglich in Delphi-Entwickler-Magazin. Sources.zip









Ein recycling Fabrik-Muster in delphi


Ein recycling Fabrik-Muster in delphi : Mehreren tausend Tipps, um Ihr Leben einfacher machen.


Die Probleme der Verwendung und Wiederverwendung von vielen unterschiedlicher Größe-Objekten in einer Anwendung können die Fragmentierung des Heap führen, die Verarbeitungsgeschwindigkeit verlangsamen können. In diesem Artikel verwendet ein Factory-Objekt zu machen und Objekte mit minimalen Fragmentierung Auswirkungen zu recyceln.
Eines der Muster in das klassische Buch 'Design Patterns; Elemente der Reusable Object-Oriented Software'ist die Factory-Methode, wobei Objekte erstellt und vor kurzem hatte ich es zu benutzen. Der Grund dafür? Ein Speicherproblem Fragmentierung in ein Simulationssystem, verwenden eine große Anzahl von Objekten zum numerischen Arrays enthalten. Gab es mehrere numerische Arraytypen, in festen Größen variierend von 1500 X 5000 x 1-10 Nummern entweder ganze Zahlen oder Doppelzimmer. Diese wurden in einer Simulation einer finanzielle Berechnung über einen Zeitraum von zwei Jahren erstellen Daten auf jedem 472 simulierten Tagen aus historischen Daten eingesetzt. An jedem Tag war Daten aus einer Datenbank gelesen, verarbeitet, dann heraus gespeichert.
Trotz umfangreichen Leck überprüfen, würde die Software nur für eine Reihe von simulierten Tagen vor dem Essen bis die Windows-Auslagerungsdatei ausgeführt. Memory-Leaks wurden sorgfältig aufgespürt und eliminiert, aber mein Haar war immer noch in Gefahr. Die app würde nicht länger als ca. 30 simulierten Tage bevor es mehr als die Hälfte der NT Paging Datei - dies auf einem 512 Mb-Ram-System begangen hatte laufen! Schließen Sie Untersuchung ergab, dass an jedem Tag lief es, der reservierte Speicher von 5M auf ca. 80Mb vergrößert wurde, dann zurück zu ca. 5 M wieder zu verkleinern. Auf den ersten Blick zeigte kein Problem mit 512 Mb zu spielen mit, aber gerade der Win NT-Taskmanager eine zunehmende Menge an Arbeitsspeicher begangen.
FRAGMENTIERUNG
Das Problem war einfach, es war Heapfragmentierung Schuld. Dies passiert, wenn viele verschiedene Objekte erstellt und dann immer wieder zerstört. Jedes Objekt erstellt wird, verbraucht es Speicher aus dem Heap. Wenn Objekte wurden erstellt und dann in umgekehrter Reihenfolge zerstört würde nicht es wohl passieren, wie alle freigegebene Speicher in einem großen Block zusammengeführt werden könnten. Aber in jedem System mit einer großen Anzahl von Objekten die Reihenfolge der Schöpfung und Zerstörung werden nie symmetrisch - meine app kann leicht bis zu 50.000 Objekte im Speicher haben, zur gleichen Zeit. Wenn ein Objekt zerstört wird, wird ein Zeiger auf den freigegebenen Speicher-Block frei-Sperrliste hinzugefügt.
Wenn andere Anforderungen für Arbeitsspeicher vorgenommen werden, versucht Windows, diese Anforderungen aus der freigegebenen Liste zuerst zuweisen. Fragmentierung passiert wo ein großer Block wie 1Mb wurde angefordert und später freigegeben, gefolgt von einer Anforderung für einen kleineren Block. Dies ist der erste Block über die kostenlose Liste entnommen, die der 1 Mb, kann gut sein, der nur 900 Kb frei lässt. Dann eine weitere Anforderung für einen großen Block 1Mb kommt, es kann nicht aus der Freiliste zufrieden sein und es also aus dem Heap stammt. Wenn der Zyklus der Schöpfung/Zerstörung oft genug die große Blöcke auf dem Heap geschieht sind in kleinere Stücke gehackt; der physische Ram ist erschöpft und mit virtueller Ram ersetzt. Windows-Heap-Speichermanagement (und Delphi) ist ziemlich clever-It braucht viel um es zu fragmentieren. Aber unter dem unerbittlichen Druck einer großen Anzahl von Objekten erstellt und zerstört werden, der Speicher-Manager wird allmählich in der Höhle.
Wenn Windows läuft aus freien Ram, es beginnt Seiten RAM Disk und Leistung auszulagern, nimmt einen Sturzflug. Ihre app könnte glücklich zusammen bei 100 % CPU im Galopp werden bis zu swappen beginnt. Es wird dann ein Trauermarsch Crawlen entlang vielleicht 7-10 % der CPU, wobei immer ausgeführt. Katastrophe!
Microsoft habe viel Mühe, die den Speicher-Manager so effizient wie möglich zu machen. Unter NT gibt es zum Beispiel ein zweistufigen Prozess der reservieren und Speicher zu begehen. Wenn Ihre app 100 Mb erfordert, ist es vorbehalten, wenn die app geladen wird. Aber nur, wenn der Speicher zugegriffen wird sind die Reserve-Seiten begangen. Wenn Sie mehr als Sie jemals möglicherweise müssen über dieses und andere Themen kennen lernen möchten, ich empfehle das Buch Inside NT, herausgegeben von Microsoft Press, sondern erhalten die David Solomon Fassung der späteren Ausgabe nicht Helen Custer Erstausgabe.
FABRIK-MUSTER
Also ich mit ihnen, nicht zersplittert derart viele Objekte zu schaffen brauchte, sie wegzuwerfen und dann tut es wieder ohne Windows virtuellen Speicher zur Neige. Das Muster-Buch vor kurzem gelesen, dachte ich, warum keine Fabrik, d. h. ein Factory-Objekt, die Objekte einer Klasse erstellt. Ich ging besser und machte es umweltfreundlich, so wird es, alle hergestellten Objekte statt vernichten und die zugehörigen zersplittert problemlos zu recyceln. Das Tüpfelchen auf dem i war das Werk in der Lage, seine Kapazitäten ohne Verlust der Zugriffsgeschwindigkeit ausbauen lassen.
Anstatt eine Factory-Klasse für alle Klassentypen haben, habe ich den einfacheren Ansatz des Führens der Object-Klasse in die Fabrik als eine Fabrik-Erstellungsparameter. Wenn die Fabrik erstellt wird, geben Sie sowohl Klasse von Objekten, die sie vornehmen kann und die anfängliche Speicherkapazität der Fabrik. Diese Größe kann geändert werden, nach oben durch Aufrufen der GrowFactory-Methode. Ich schlage vor, dass Sie dies nur in Ausnahmefällen (!) Umständen aufrufen.
Der Link zu der Fabrik der einzelnen Objekte ist erforderlich, damit alle 'Fabrik hergestellt-Objekte' (FMO) von einer TFactoryObject Klasse statt Tobject absteigen müssen. Dies fügt einen Fabrik-Verweis die 'gestempelt ist' auf alle FMO, so dass das Objekt, welche Fabrik weiß verwenden, um selbst zu recyceln.
Anstatt ein Objekt Ihrer app Anfragen einer werkseitig geeignet durch Aufrufen der RequestObj-Methode, die ein Tclass-Objekt zurückgibt zurück und Sie ihn in die richtige Klasse mit 'als' umwandeln. Schließlich wenn Sie fertig sind mit dem Objekt rufen Sie nur die RecycleSelf-Methode. Keine Erstellung oder Zerstörung mit Ausnahme der Fabriken selbst.
WIE ES FUNKTIONIERT

Wenn die Fabrik erstellt wird, werden alle Objekte physikalisch in einen zusammenhängenden Block RAM erstellt. Ein Tlist (Fblocklist)-Objekt enthält die Adresse eines jeden dieser Blöcke. Jedes Mal, wenn Sie das Werk wachsen ein neuer Block erstellt und in diese Liste aufgenommen. Die Methode AddObjects erstellt die angegebene Anzahl von Objekten mit dem Ram aus dem Block. Wenn Sie schreiben sein Code wie diesen bewusst, dass gerade dabei eine tobject(address) nicht ausreicht um das Objekt zu erstellen. Sie müssen immer ObjectClass.InitInstance(address) um es in eine 'richtige' Objekt transformieren aufrufen. InitInstance löscht alles auf NULL, NULL etc., aber noch wichtiger ist es die VMT richtet.
Das Werk enthält auch eine andere Tlist (Ffreelist), die die Adresse alle nicht verwendeten Objekts enthält.
Alle Esel Arbeit der Füllung der Fabrik in die private Methode AddObjects unternommen. Für jedes Objekt im Block erstellt konvertiert diese in ein Objekt mit FactoryObject als die Klasse des Objekts erstellt die Zeiger Ptr. Dies muss immer ein Nachkomme des TfactoryObject sein. Obj hält den Objektverweis und verbindet die Fabrik hergestellten Objekt. PTR ist dann inkrementiert, um zum nächsten Objekt im Block zu zeigen, indem Sie hinzufügen Fsize.
Zum Abrufen eines Objekts sind Sie Code ruft Request_Obj, erscheint der Hinweis am Ende der Ffreelist und als das erste angeforderte Objekt zurückgibt. Recycling ist das Gegenteil; Es legt den recycelten Objektverweis auf das Ende des Ffreelist. Eine Sache zu beachten. Wenn eine Fabrik hergestellt Objekt verwendet wird, hat die Fabrik jeder Verweis darauf, keine, obwohl der vom Objekt belegte Speicher innerhalb der Fabrik enthalten ist!
ERSTELLEN UND ZERSTÖREN ERSETZEN
Die Fabrik müssen Sie hergestellten Objekte etwas anders von 'normal' verwenden. Sie nicht mehr erstellen oder explizit zu befreien, statt Sie nur die relevante Fabrik für das Objekt anfordern. Es sei denn, die Fabrik leer ist funktioniert das immer. Du musst die Initialisierung Code im Konstruktor und Terminierungscode in den Destruktor-Routinen ändern. Es gibt zwei Ansätze.
1) Wenn das Objekt verfügt über eine einfache Erstellen Konstruktor ohne Parameter, können Sie benennen sie Prozedur init; außer Kraft setzen und entfernen Sie alle geerbten erstellen-Aufrufe. Die Fabrik wird immer eine Init-Methode, wenn ein Objekt angefordert wird. Standardmäßig tut dies nichts, aber Sie können dies überschreiben, so dass Ihre Init automatisch auf jedes Objekt angefordert ab Werk aufgerufen wird.
2) Wenn Ihre ursprüngliche erstellen Parameter hat, benennen Sie sie um so etwas wie Initialise und entfernen Sie geerbte etc. Aufrufe. Nach dem Objekt ist angeforderte Aufruf der Routine Initialise, zB MyRoutine.Initialise(...)
Wenn das Objekt Destruktorcode, in Verfahren, die getan; umbenennen überschreiben Sie, sodass sie automatisch aufgerufen wird, wenn das Objekt wiederverwendet wird. Init und fertig sind ähnlich zu erstellen/zu zerstören, aber ohne das Gepäck der Mechanismus der Konstruktion oder Zerstörung.
Als einen kleinen Exkurs Wissens meines gibt es Argumente in der Delphi-Welt dafür auf einen Teil von Arbeitsplätzen oder Teil einer zweiteiligen ist, wo der Konstruktor über Parameter verfügt und das Objekt vollständig richtet. In der zweiteiligen Ansatz erstellt der Konstruktor nur ein leeres Objekt, das dann durch eine neuere Methode initialisiert wird. Der Factory-Ansatz denke ich ist fest im zweiteiligen Lager...
Wenn die Fabrik zerstört wird, werden die zugewiesenen Speicherblöcke freigegeben. Vor diesem überprüft das Werk, dass die Anzahl der Objekte in der Freelist die Kapazität entspricht. Wenn Sie vergessen haben, Ihre verbleibenden Objekte wiederverwenden, wird eine Ausnahme ausgelöst.
VERGLEICH-PROGRAMM
Dies zeigt die Vorteile von Fabriken... Bei der Arbeit meine app hatte viele verschiedene Größen der Objekte in unterschiedlichen Mengen, aber ein 15.000 Linie-Programm wäre nicht gerade veröffentlichungsreife. Nach einer Weile des Ausprobierens kam ich mit einem kurzen Programm, das Fragmentierung zeigen kann. Dies hängt jedoch die Größe der verschiedenen Objekte, wie viele es sind, freier Arbeitsspeicher und für wie lange er läuft. Auch scheint Fragmentierung, schneller auf NT4. 0 als 98, was darauf hindeutet, dass vielleicht 98 hat eine bessere Speicherverwaltung auftreten. Beim Ausführen wird erstellt und eine große Anzahl von Objekten immer wieder für die angegebene Anzahl von Tagen zerstört. Es tut auch genau das gleiche, die mithilfe einer Factory. Jeden Tag ist so terminiert, und beide Male geplant verwendend Tchart.
Ich habe drei Typen von Objekten, von tTestobj die von Tfactoryobject senkt sich alle abstammen. Kleine Objekte sind 2 K groß, Medium sind 40K und groß sind 800K, aber diese Größen werden durch Konstanten definiert und können leicht geändert. Das Demoprogramm weist 100Mb für die normale Objekte und eine weitere 100Mb für die Fabrik. Beide enthalten die gleiche Anzahl von Objekten-gleichmäßig aufgeteilt nach Größe zwischen den drei Objekttypen, so gibt es 17406 kleine Objekte, 873 Medium und große 43. In der Objekt-Erstellungsverfahren TimeOneDay sind diese nach dem Zufallsprinzip erstellt und zur Liste hinzugefügt. Am Ende des Tages werden sie freigegeben werden und der Vorgang wiederholt am nächsten Tag.
Das gleiche geschieht mit drei Fabriken mit alle hergestellten Objekte, die eine Factorydata-Liste hinzugefügt. Auf einer P2-400 mit 256Mb läuft für 100 Tage gab es ein moderaten Anstieg der die Zeit für die Fabrik und die normalen Objekterstellung. Kommentieren Sie die normale Einrichtung bestätigt, dass dieser Verdacht-der Anstieg war viel weniger über 1000 täglich laufen sowohl Normal als auch Werk mit Fabriken gegen 100 Tage. Ich vermutete, dass dies durch erhöhte Seite aufgrund von Fragmentierung Auswirkungen auf beide Prozesse Auslagern verursacht wurde. Einige andere Kombinationen von Größen und Anzahl der Objekte unter Windows 98 zeigte keine Fragmentierung
Ich dies implementiert, ursprünglich mit einem Tlist für Testdata und Factorydata und später geändert, als ich merkte, dass wiederholt hinzufügen und Freigeben von 18000 Zeiger auch Heapfragmentierung hinzugefügt wurde. Ich bin nicht dafür Notwasserung Tstringlists vollständig in Ihrem Code-sie sind sehr nützlich, (wie Tlists), aber haben Sie eine große Anzahl von Elementen zu manipulieren, es wäre besser, eigene Liste Strukturen zu verwenden. Möchten Sie für diesen Zweck, die wahrscheinlich besser, die Struktur mit Null-Zeigern, vollständig auszufüllen, damit das zählen Tlist oder Tstringlist verwenden = Kapazität und eine ganze Zahl für den Index des letzten Pointer verwenden.
Diese app auch bestätigt, dass der Fabrik-Code ist sehr schnell bei der Zuweisung und löschen-in der Regel 30 ms für 18000 Objekte anstelle der 870 ms, dass normale anlegen/löschen nahm.
------------------------------------------------
Tgis Artikel erschien ursprünglich in Delphi-Entwickler-Magazin. Sources.zip


Ein recycling Fabrik-Muster in delphi

Ein recycling Fabrik-Muster in delphi : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
Ein recycling Fabrik-Muster in delphi
Wiezutun
Freunden empfehlen
  • gplus
  • pinterest

Kommentar

Einen Kommentar hinterlassen

Wertung