Une usine de recyclage de modèle en delphi
Les problèmes d'utilisation et de réutilisation de nombreux variant la taille des objets dans une application peut provoquer la fragmentation du tas qui peuvent ralentir la vitesse de traitement. Cet article utilise un objet de fabrique, de fabriquer et recycler des objets avec un minimum d'effets de la fragmentation.
l'Un des modèles dans le livre classique de 'Modèles de Conception des Éléments de Logiciels Orientés Objets Réutilisables' est la méthode de fabrique, où les objets sont créés et j'ai récemment eu à l'utiliser. La raison? Un problème de la fragmentation de la mémoire dans un système de simulation à l'aide d'un grand nombre d'objets à tenir des tableaux numériques. Il y avait plusieurs tableau numérique types, dimensions fixes variant de 1500 x de 1 à 5000 x 10 nombres entiers ou en double. Elles ont été utilisées dans une simulation de calcul financier sur une période de deux ans, la création de données sur chacun de 472 simulé jours à partir de données historiques. Chaque jour, les données sont lues à partir d'une base de données, traitées, puis enregistré.
Malgré une importante fuite de la vérification, le logiciel ne fonctionnera que pour un certain nombre de simulation de jours avant de manger le fichier d'échange de Windows. Les fuites de mémoire ont été soigneusement traqué et éliminé, mais mes cheveux étaient encore en danger. L'application serait de ne pas fonctionner pendant plus de 30 simulé jours avant il avait commis plus de la moitié de la NT fichier d'échange - ce sur un 512 Mo de ram système! Proche de l'enquête a montré que chaque jour, il a couru, la mémoire allouée a augmenté de 5 m à environ 80 mo puis de le réduire à environ 5M de nouveau. Sur le visage de celui-ci, n'est pas un problème avec 512 mo de jouer avec, mais en regardant la Win NT le Gestionnaire des Tâches a montré une augmentation de la quantité de mémoire engagé.
la FRAGMENTATION
Le problème était simple, c'était de la fragmentation des segments à blâmer. Cela se produit lorsque de nombreux objets différents sont créés et détruits à plusieurs reprises. Comme chaque objet est créé, il consomme de la mémoire dans le tas. Si des objets ont été créés et détruits dans l'ordre inverse, il ne serait probablement pas tous la mémoire libérée pourraient être fusionnés en un seul grand bloc. Mais dans n'importe quel système avec un grand nombre d'objets de l'ordre de la création et de la destruction ne sera jamais symétrique - mon application peut facilement avoir jusqu'à 50 000 objets en mémoire en même temps. Alors, lorsqu'un objet est détruit, un pointeur vers la mémoire libérée bloc est ajouté à une zone de libre-bloc de la liste.
si d'autres demandes de la mémoire sont en fait, Windows tente d'allouer ces demandes de le libéré de la liste de la première. La Fragmentation se produit lorsqu'un grand bloc de 1 mo a été demandé et ensuite libérée, suivi d'une demande d'un bloc plus petit. Ceci est pris à partir du premier bloc sur le libre-liste qui pourrait bien être le 1 mo, ce qui laisse seulement 900 ko gratuit. Puis une autre demande pour un grand bloc de 1 mo qui vient, il ne peut pas être satisfait de la liste libre et donc il est pris dans le tas. Si la création/destruction de cycle se produit assez souvent les grands blocs sur le tas sont hachés en petits morceaux de la ram physique est évacué et remplacé par ram virtuelle. Tas de Windows gestion de la mémoire (et Delphi) est très habile de sa part - il en faut beaucoup pour l'obtenir à un fragment. Mais sous la pression constante d'un grand nombre d'objets créés et détruits, le gestionnaire de mémoire va progressivement s'affaisser.
Lorsque Windows s'exécute hors de la ram libre, il commence la permutation de pages de mémoire vive sur le disque et la performance prend un nez de plongée. Votre application peut être galopant joyeusement le long du PROCESSEUR de 100% jusqu'à ce que la permutation commence. Il devient alors une marche funèbre à ramper le long des peut-être de 7 à 10% de CPU, de prendre leur temps pour s'exécuter. Catastrophe!
Microsoft ont mis beaucoup d'efforts le gestionnaire de mémoire aussi efficace que possible. Par exemple sous windows NT, il y a un processus à deux étapes de la réservation et le commettre à la mémoire. Si votre application nécessite de 100 mo, il est réservé lors du chargement de l'application. Mais seulement lorsque la mémoire est accédée sont la réserve pages commis. Si vous souhaitez en apprendre plus que vous aurez peut-être besoin de savoir à ce sujet et d'autres sujets, je vous recommande le livre à l'Intérieur de NT, publié par Microsoft Press, mais obtenir le David Solomon version qui est la plus tard édition, le Helen Custer première édition.
MODÈLE de FABRIQUE
j'ai Donc besoin d'un non fragmentation façon de créer de nombreux objets, de les utiliser, de les jeter et puis de le faire tout de nouveau sans windows en cours d'exécution hors de la mémoire virtuelle. Ayant lu récemment le livre de Patron j'ai pensé pourquoi ne pas utiliser une usine, c'est à dire un objet usine qui crée des objets de la classe spécifiée. Ensuite, je suis allé un mieux et il a fait respectueux de l'environnement, de sorte qu'il devient de recycler tous ses objets manufacturés au lieu de les détruire et sans les problèmes de fragmentation. La cerise sur le gâteau a été de faire de l'usine en mesure de développer ses capacités, sans perte de vitesse d'accès.
Plutôt que d'avoir une usine de classe pour tous les types de classe, j'ai pris l'approche la plus simple de passer de la classe de l'objet dans l'usine de l'usine paramètre de création. Lorsque l'usine est créée vous spécifiez à la fois la classe des objets qu'il peut faire et l'initiale de la capacité de stockage de l'usine. Cette taille peut être modifiée à la hausse par l'appel de la GrowFactory méthode. Je vous suggère de vous appeler que cela exceptionnelles (!) circonstances.
Le lien de retour à l'usine à partir de chaque objet est nécessaire, de sorte que tous les 'faite à l'usine des objets' (FMOs) doit descendre d'un TFactoryObject classe au lieu de Tobject. Cela ajoute une référence de l'usine qui est 'estampillé' sur tous les FMOs de sorte que l'objet ne sait qui de l'usine à l'utilisation de recycler lui-même.
au Lieu de créer un objet de votre application fait la demande auprès du adapté à l'usine par l'appel de sa RequestObj méthode qui renvoie une tclass objet de dos et de vous convertir à la bonne classe à l'aide de 'comme'. Enfin, lorsque vous avez fini d'utiliser l'objet que vous venez d'appeler ses RecycleSelf méthode. Pas de création ou de destruction à l'exception des usines elles-mêmes.
COMMENT ÇA marche
Lorsque l'usine est créée, tous les objets sont physiquement créé dans un bloc contigu de mémoire vive. Une tlist (fblocklist) objet contient l'adresse de chacun de ces blocs. Chaque fois que vous grandir l'usine, un nouveau bloc est créé et ajouté à cette liste. La méthode AddObjects crée le nombre spécifié d'objets à l'aide de la ram à partir du bloc. Si vous écrivez du code comme ceci sachez que faire juste un tobject(adresse) n'est pas suffisant pour créer l'objet. Vous devez toujours faire appel à ObjectClass.InitInstance(adresse) pour le transformer en un ' bon ' objet. InitInstance efface tout à zéro, nul, etc, mais plus important encore, il met en place le VMT.
L'usine contient également une autre tlist (ffreelist) qui contient l'adresse de chaque inutilisés de l'objet.
l'Ensemble de l'âne du remplissage de l'usine est fait dans la méthode privée AddObjects. Pour chaque objet créé dans le bloc, cela transforme le pointeur ptr dans un objet, en utilisant FactoryObject que la classe de l'objet créé. Cela doit toujours être un descendant de TfactoryObject. Obj détient l'objet de référence et des liens de l'usine de l'objet fabriqué. ptr est ensuite incrémenté pour pointer vers l'objet suivant dans le bloc en ajoutant fsize.
Pour obtenir un objet que vous avez r les appels de code Request_Obj qui apparaît la référence à la fin de la ffreelist et la retourne sous le premier objet demandé. Le recyclage est l'inverse de la pousse du recyclage de l'objet de référence sur la fin de ffreelist. Une chose à garder à l'esprit. Quand une usine a fait l'objet est en cours d'utilisation, l'usine n'a pas de référence, bien que la mémoire occupée par l'objet est contenu à l'intérieur de l'usine!
REMPLACEMENT de CRÉER ET de DÉTRUIRE des
à l'Aide de l'usine nécessite d'utiliser les objets fabriqués de façon un peu différente de la normale. Vous n'avez plus à créer ou à les libérer explicitement, au lieu que vous venez de demande pertinentes de l'usine de l'objet. À moins que l'usine est vide ce le sera toujours. Vous devez modifier le code d'initialisation dans le constructeur et le code d'arrêt dans le destructeur de routines. Il y a deux approches.
1) Si l'objet est simple de créer constructeur sans paramètres, vous pouvez le renommer à la procédure init remplacer et supprimer tout hérité de créer des appels. L'usine appelle toujours une méthode Init lorsqu'un objet est demandé. Par défaut, cela ne donne rien, mais vous pouvez le modifier afin que votre Init est appelée automatiquement à chaque objet demandé de l'usine.
2) Si votre original créer des paramètres, le renommer en quelque chose comme Initialiser et supprimer hérité etc appels. Après que l'objet est demandé d'appel de l'initialisation de routine, par exemple, MyRoutine.Initialiser(...)
Si l'objet a de destructeur de code, de le renommer à la procédure Fait remplacer, de sorte qu'elle est appelée automatiquement lorsque l'objet est recyclé. Init et de Fait sont similaires à créer/détruire, mais sans les bagages de la construction ou la destruction mécanisme.
Comme une légère digression, je comprends qu'il y a des arguments dans le Delphi monde en faveur d'une seule partie de la création ou de deux parties, Une partie est là que le constructeur a des paramètres et configure complètement l'objet. Dans les deux approche de la partie, le constructeur crée un objet vide qui est ensuite initialisé par un plus tard méthode. L'usine approche, je pense fermement dans les deux parties du camp..
Lorsque l'usine est détruite, tous les blocs de mémoire alloués sont libérés. Avant cela, l'usine vérifie que le nombre d'objets dans la freelist correspond à la capacité. Si vous avez oublié de recycler tous vos objets restants, il déclenche une exception.
PROGRAMME de COMPARAISON
Cela montre les avantages d'usines.. Au travail mon application a beaucoup de différentes tailles des objets de la différence de quantité, mais de 15 000 programme en ligne ne serait pas exactement être publiable. Après un peu d'essais et d'erreurs, je suis venu avec un programme court qui peut montrer la fragmentation. Cependant cela dépend de la taille des différents objets, combien il y en a, de la mémoire vive disponible et pour combien de temps il est exécuté. Aussi, la fragmentation semble se produire plus rapidement sur NT4.0 de 98 qui suggère que peut-être 98 a un meilleur gestionnaire de mémoire. Lorsqu'il est exécuté, il crée et détruit un grand nombre d'objets à plusieurs reprises pour le nombre de jours spécifié. Il a également fait exactement la même chose à l'aide d'une usine. Chaque jour est chronométré et les deux ensembles de fois tracée à l'aide de Tchart.
j'ai utilisé trois types d'objets, tous les descendants de tTestobj, qui descend de Tfactoryobject. Les petits objets sont 2 dans la taille, la moyenne sont 40K et grands sont 800K, mais ces montants sont définis par des constantes et peut facilement changé. Le programme de démonstration alloue 100 mo pour les objets normaux et un autre de 100 mo pour l'usine. Les deux contiennent le même nombre d'objets - divisé à parts égales par la taille entre les trois types d'objet il y a donc 17406 de petits objets, 873 moyenne et 43 grande. Dans la création de l'objet de la procédure TimeOneDay ces sont créés de manière aléatoire et ajouté à la liste. À la fin de la journée, ils sont libérés et le procédé se répète jour suivant.
de La même manière à l'aide de trois usines avec tous les objets fabriqués ajouté à un factorydata liste. Sur un P2 400 avec 256 mo de 100 jours, il y avait une augmentation modeste dans le temps à l'usine et de la création de l'objet. Commentant la normale création confirmé cette hypothèse, la hausse a été beaucoup moins 1000 course de la journée en utilisant les usines contre 100 jours, avec à la fois normal et essais en usine. J'ai deviné que c'était causé par l'augmentation de l'échange de la page en raison de la fragmentation affectant à la fois les processus. Certains autres combinaisons de tailles et le nombre d'objets sous Windows 98 n'a montré aucune fragmentation
j'ai mis en place cette origine à l'aide d'une tlist pour les deux testdata et factorydata et changé plus tard, lorsque j'ai réalisé que l'ajout répété et à la libération de 18000 pointeurs était également l'ajout de la fragmentation du segment. Je ne préconise pas d'amerrissage tstringlists complètement dans votre code, ils sont très utiles (comme le sont les tlists), mais si vous devez manipuler un grand nombre d'éléments, il pourrait être préférable d'utiliser votre propre liste de structures. Si vous souhaitez utiliser Tlist ou Tstringlist à cette fin, c'est probablement mieux pour remplir complètement la structure à néant les pointeurs, de sorte que count = capacité et de l'utilisation d'un nombre entier de tenir l'index de la dernière pointeur.
Cette application a également confirmé que le code d'usine est très rapide au moment de la répartition et de la suppression - généralement de 30 ms pour 18000 objets au lieu de 870 mme que la normale de la création/suppression a eu.
& & & & & & & & & & & & & & & & & & & & & & & &
Tgis article est paru initialement dans les Développeur Delphi magazine. Sources.zip
Une usine de recyclage de modele en delphi
Une usine de recyclage de modele en delphi : Plusieurs milliers de conseils pour vous faciliter la vie.
Les problemes d'utilisation et de reutilisation de nombreux variant la taille des objets dans une application peut provoquer la fragmentation du tas qui peuvent ralentir la vitesse de traitement. Cet article utilise un objet de fabrique, de fabriquer et recycler des objets avec un minimum d'effets de la fragmentation.
l'Un des modeles dans le livre classique de 'Modeles de Conception des Elements de Logiciels Orientes Objets Reutilisables' est la methode de fabrique, ou les objets sont crees et j'ai recemment eu a l'utiliser. La raison? Un probleme de la fragmentation de la memoire dans un systeme de simulation a l'aide d'un grand nombre d'objets a tenir des tableaux numeriques. Il y avait plusieurs tableau numerique types, dimensions fixes variant de 1500 x de 1 a 5000 x 10 nombres entiers ou en double. Elles ont ete utilisees dans une simulation de calcul financier sur une periode de deux ans, la creation de donnees sur chacun de 472 simule jours a partir de donnees historiques. Chaque jour, les donnees sont lues a partir d'une base de donnees, traitees, puis enregistre.
Malgre une importante fuite de la verification, le logiciel ne fonctionnera que pour un certain nombre de simulation de jours avant de manger le fichier d'echange de Windows. Les fuites de memoire ont ete soigneusement traque et elimine, mais mes cheveux etaient encore en danger. L'application serait de ne pas fonctionner pendant plus de 30 simule jours avant il avait commis plus de la moitie de la NT fichier d'echange - ce sur un 512 Mo de ram systeme! Proche de l'enquete a montre que chaque jour, il a couru, la memoire allouee a augmente de 5 m a environ 80 mo puis de le reduire a environ 5M de nouveau. Sur le visage de celui-ci, n'est pas un probleme avec 512 mo de jouer avec, mais en regardant la Win NT le Gestionnaire des Taches a montre une augmentation de la quantite de memoire engage.
la FRAGMENTATION
Le probleme etait simple, c'etait de la fragmentation des segments a blamer. Cela se produit lorsque de nombreux objets differents sont crees et detruits a plusieurs reprises. Comme chaque objet est cree, il consomme de la memoire dans le tas. Si des objets ont ete crees et detruits dans l'ordre inverse, il ne serait probablement pas tous la memoire liberee pourraient etre fusionnes en un seul grand bloc. Mais dans n'importe quel systeme avec un grand nombre d'objets de l'ordre de la creation et de la destruction ne sera jamais symetrique - mon application peut facilement avoir jusqu'a 50 000 objets en memoire en meme temps. Alors, lorsqu'un objet est detruit, un pointeur vers la memoire liberee bloc est ajoute a une zone de libre-bloc de la liste.
si d'autres demandes de la memoire sont en fait, Windows tente d'allouer ces demandes de le libere de la liste de la premiere. La Fragmentation se produit lorsqu'un grand bloc de 1 mo a ete demande et ensuite liberee, suivi d'une demande d'un bloc plus petit. Ceci est pris a partir du premier bloc sur le libre-liste qui pourrait bien etre le 1 mo, ce qui laisse seulement 900 ko gratuit. Puis une autre demande pour un grand bloc de 1 mo qui vient, il ne peut pas etre satisfait de la liste libre et donc il est pris dans le tas. Si la creation/destruction de cycle se produit assez souvent les grands blocs sur le tas sont haches en petits morceaux de la ram physique est evacue et remplace par ram virtuelle. Tas de Windows gestion de la memoire (et Delphi) est tres habile de sa part - il en faut beaucoup pour l'obtenir a un fragment. Mais sous la pression constante d'un grand nombre d'objets crees et detruits, le gestionnaire de memoire va progressivement s'affaisser.
Lorsque Windows s'execute hors de la ram libre, il commence la permutation de pages de memoire vive sur le disque et la performance prend un nez de plongee. Votre application peut etre galopant joyeusement le long du PROCESSEUR de 100% jusqu'a ce que la permutation commence. Il devient alors une marche funebre a ramper le long des peut-etre de 7 a 10% de CPU, de prendre leur temps pour s'executer. Catastrophe!
Microsoft ont mis beaucoup d'efforts le gestionnaire de memoire aussi efficace que possible. Par exemple sous windows NT, il y a un processus a deux etapes de la reservation et le commettre a la memoire. Si votre application necessite de 100 mo, il est reserve lors du chargement de l'application. Mais seulement lorsque la memoire est accedee sont la reserve pages commis. Si vous souhaitez en apprendre plus que vous aurez peut-etre besoin de savoir a ce sujet et d'autres sujets, je vous recommande le livre a l'Interieur de NT, publie par Microsoft Press, mais obtenir le David Solomon version qui est la plus tard edition, le Helen Custer premiere edition.
MODELE de FABRIQUE
j'ai Donc besoin d'un non fragmentation façon de creer de nombreux objets, de les utiliser, de les jeter et puis de le faire tout de nouveau sans windows en cours d'execution hors de la memoire virtuelle. Ayant lu recemment le livre de Patron j'ai pense pourquoi ne pas utiliser une usine, c'est a dire un objet usine qui cree des objets de la classe specifiee. Ensuite, je suis alle un mieux et il a fait respectueux de l'environnement, de sorte qu'il devient de recycler tous ses objets manufactures au lieu de les detruire et sans les problemes de fragmentation. La cerise sur le gateau a ete de faire de l'usine en mesure de developper ses capacites, sans perte de vitesse d'acces.
Plutot que d'avoir une usine de classe pour tous les types de classe, j'ai pris l'approche la plus simple de passer de la classe de l'objet dans l'usine de l'usine parametre de creation. Lorsque l'usine est creee vous specifiez a la fois la classe des objets qu'il peut faire et l'initiale de la capacite de stockage de l'usine. Cette taille peut etre modifiee a la hausse par l'appel de la GrowFactory methode. Je vous suggere de vous appeler que cela exceptionnelles (!) circonstances.
Le lien de retour a l'usine a partir de chaque objet est necessaire, de sorte que tous les 'faite a l'usine des objets' (FMOs) doit descendre d'un TFactoryObject classe au lieu de Tobject. Cela ajoute une reference de l'usine qui est 'estampille' sur tous les FMOs de sorte que l'objet ne sait qui de l'usine a l'utilisation de recycler lui-meme.
au Lieu de creer un objet de votre application fait la demande aupres du adapte a l'usine par l'appel de sa RequestObj methode qui renvoie une tclass objet de dos et de vous convertir a la bonne classe a l'aide de 'comme'. Enfin, lorsque vous avez fini d'utiliser l'objet que vous venez d'appeler ses RecycleSelf methode. Pas de creation ou de destruction a l'exception des usines elles-memes.
COMMENT ÇA marche
Lorsque l'usine est creee, tous les objets sont physiquement cree dans un bloc contigu de memoire vive. Une tlist (fblocklist) objet contient l'adresse de chacun de ces blocs. Chaque fois que vous grandir l'usine, un nouveau bloc est cree et ajoute a cette liste. La methode AddObjects cree le nombre specifie d'objets a l'aide de la ram a partir du bloc. Si vous ecrivez du code comme ceci sachez que faire juste un tobject(adresse) n'est pas suffisant pour creer l'objet. Vous devez toujours faire appel a ObjectClass.InitInstance(adresse) pour le transformer en un ' bon ' objet. InitInstance efface tout a zero, nul, etc, mais plus important encore, il met en place le VMT.
L'usine contient egalement une autre tlist (ffreelist) qui contient l'adresse de chaque inutilises de l'objet.
l'Ensemble de l'ane du remplissage de l'usine est fait dans la methode privee AddObjects. Pour chaque objet cree dans le bloc, cela transforme le pointeur ptr dans un objet, en utilisant FactoryObject que la classe de l'objet cree. Cela doit toujours etre un descendant de TfactoryObject. Obj detient l'objet de reference et des liens de l'usine de l'objet fabrique. ptr est ensuite incremente pour pointer vers l'objet suivant dans le bloc en ajoutant fsize.
Pour obtenir un objet que vous avez r les appels de code Request_Obj qui apparaît la reference a la fin de la ffreelist et la retourne sous le premier objet demande. Le recyclage est l'inverse de la pousse du recyclage de l'objet de reference sur la fin de ffreelist. Une chose a garder a l'esprit. Quand une usine a fait l'objet est en cours d'utilisation, l'usine n'a pas de reference, bien que la memoire occupee par l'objet est contenu a l'interieur de l'usine!
REMPLACEMENT de CREER ET de DETRUIRE des
a l'Aide de l'usine necessite d'utiliser les objets fabriques de façon un peu differente de la normale. Vous n'avez plus a creer ou a les liberer explicitement, au lieu que vous venez de demande pertinentes de l'usine de l'objet. A moins que l'usine est vide ce le sera toujours. Vous devez modifier le code d'initialisation dans le constructeur et le code d'arret dans le destructeur de routines. Il y a deux approches.
1) Si l'objet est simple de creer constructeur sans parametres, vous pouvez le renommer a la procedure init remplacer et supprimer tout herite de creer des appels. L'usine appelle toujours une methode Init lorsqu'un objet est demande. Par defaut, cela ne donne rien, mais vous pouvez le modifier afin que votre Init est appelee automatiquement a chaque objet demande de l'usine.
2) Si votre original creer des parametres, le renommer en quelque chose comme Initialiser et supprimer herite etc appels. Apres que l'objet est demande d'appel de l'initialisation de routine, par exemple, MyRoutine.Initialiser(...)
Si l'objet a de destructeur de code, de le renommer a la procedure Fait remplacer, de sorte qu'elle est appelee automatiquement lorsque l'objet est recycle. Init et de Fait sont similaires a creer/detruire, mais sans les bagages de la construction ou la destruction mecanisme.
Comme une legere digression, je comprends qu'il y a des arguments dans le Delphi monde en faveur d'une seule partie de la creation ou de deux parties, Une partie est la que le constructeur a des parametres et configure completement l'objet. Dans les deux approche de la partie, le constructeur cree un objet vide qui est ensuite initialise par un plus tard methode. L'usine approche, je pense fermement dans les deux parties du camp..
Lorsque l'usine est detruite, tous les blocs de memoire alloues sont liberes. Avant cela, l'usine verifie que le nombre d'objets dans la freelist correspond a la capacite. Si vous avez oublie de recycler tous vos objets restants, il declenche une exception.
PROGRAMME de COMPARAISON
Cela montre les avantages d'usines.. Au travail mon application a beaucoup de differentes tailles des objets de la difference de quantite, mais de 15 000 programme en ligne ne serait pas exactement etre publiable. Apres un peu d'essais et d'erreurs, je suis venu avec un programme court qui peut montrer la fragmentation. Cependant cela depend de la taille des differents objets, combien il y en a, de la memoire vive disponible et pour combien de temps il est execute. Aussi, la fragmentation semble se produire plus rapidement sur NT4.0 de 98 qui suggere que peut-etre 98 a un meilleur gestionnaire de memoire. Lorsqu'il est execute, il cree et detruit un grand nombre d'objets a plusieurs reprises pour le nombre de jours specifie. Il a egalement fait exactement la meme chose a l'aide d'une usine. Chaque jour est chronometre et les deux ensembles de fois tracee a l'aide de Tchart.
j'ai utilise trois types d'objets, tous les descendants de tTestobj, qui descend de Tfactoryobject. Les petits objets sont 2 dans la taille, la moyenne sont 40K et grands sont 800K, mais ces montants sont definis par des constantes et peut facilement change. Le programme de demonstration alloue 100 mo pour les objets normaux et un autre de 100 mo pour l'usine. Les deux contiennent le meme nombre d'objets - divise a parts egales par la taille entre les trois types d'objet il y a donc 17406 de petits objets, 873 moyenne et 43 grande. Dans la creation de l'objet de la procedure TimeOneDay ces sont crees de maniere aleatoire et ajoute a la liste. A la fin de la journee, ils sont liberes et le procede se repete jour suivant.
de La meme maniere a l'aide de trois usines avec tous les objets fabriques ajoute a un factorydata liste. Sur un P2 400 avec 256 mo de 100 jours, il y avait une augmentation modeste dans le temps a l'usine et de la creation de l'objet. Commentant la normale creation confirme cette hypothese, la hausse a ete beaucoup moins 1000 course de la journee en utilisant les usines contre 100 jours, avec a la fois normal et essais en usine. J'ai devine que c'etait cause par l'augmentation de l'echange de la page en raison de la fragmentation affectant a la fois les processus. Certains autres combinaisons de tailles et le nombre d'objets sous Windows 98 n'a montre aucune fragmentation
j'ai mis en place cette origine a l'aide d'une tlist pour les deux testdata et factorydata et change plus tard, lorsque j'ai realise que l'ajout repete et a la liberation de 18000 pointeurs etait egalement l'ajout de la fragmentation du segment. Je ne preconise pas d'amerrissage tstringlists completement dans votre code, ils sont tres utiles (comme le sont les tlists), mais si vous devez manipuler un grand nombre d'elements, il pourrait etre preferable d'utiliser votre propre liste de structures. Si vous souhaitez utiliser Tlist ou Tstringlist a cette fin, c'est probablement mieux pour remplir completement la structure a neant les pointeurs, de sorte que count = capacite et de l'utilisation d'un nombre entier de tenir l'index de la derniere pointeur.
Cette application a egalement confirme que le code d'usine est tres rapide au moment de la repartition et de la suppression - generalement de 30 ms pour 18000 objets au lieu de 870 mme que la normale de la creation/suppression a eu.
& & & & & & & & & & & & & & & & & & & & & & & &
Tgis article est paru initialement dans les Developpeur Delphi magazine. Sources.zip
Une usine de recyclage de modèle en delphi
By commentfaire
Une usine de recyclage de modèle en delphi : Plusieurs milliers de conseils pour vous faciliter la vie.