Optimiser l'utilisation de la mémoire de votre programme Delphi

Lors de l'écriture d'applications de longue durée - le type de programmes qui passeront la majeure partie de la journée minimisés dans la barre des tâches ou barre d'état système, il peut devenir important de ne pas laisser le programme «s'enfuir» avec l'utilisation de la mémoire.

Les deux colonnes les plus à droite indiquent l'utilisation du processeur (temps) et l'utilisation de la mémoire. Si un processus affecte sérieusement l'un de ces éléments, votre système ralentira.

Le genre de chose qui affecte fréquemment l'utilisation du processeur est un programme en boucle (demandez à tout programmeur qui a oublié de mettre une instruction "lire ensuite" dans une boucle de traitement de fichiers). Ces types de problèmes sont généralement assez facilement corrigés.

En revanche, l'utilisation de la mémoire n'est pas toujours apparente et doit être gérée plus que corrigée. Supposons par exemple qu'un programme de type capture est en cours d'exécution.

Ce programme est utilisé tout au long de la journée, peut-être pour la capture téléphonique à un service d'assistance ou pour une autre raison. Il n’est tout simplement pas logique de l’arrêter toutes les vingt minutes, puis de le redémarrer. Il sera utilisé tout au long de la journée, mais à intervalles peu fréquents.

instagram viewer

Si ce programme s'appuie sur un traitement interne lourd ou a beaucoup d'illustrations sur ses formes, tôt ou tard son utilisation de la mémoire va croître, laissant moins de mémoire pour d'autres processus plus fréquents, augmentant l'activité de pagination et, finalement, ralentissant l'ordinateur.

Disons que vous allez concevoir un programme avec le formulaire principal et deux formulaires supplémentaires (modaux). En règle générale, selon votre version de Delphi, Delphi va insérer les formulaires dans le unité de projet (Fichier DPR) et comprendra une ligne pour créer tous les formulaires au démarrage de l'application (Application. CreateForm (...)

Les lignes incluses dans l'unité de projet sont de conception Delphi et sont idéales pour les personnes qui ne connaissent pas Delphi ou qui commencent tout juste à l'utiliser. C'est pratique et utile. Cela signifie également que TOUS les formulaires vont être créés au démarrage du programme et NON quand ils seront nécessaires.

En fonction de l'objet de votre projet et des fonctionnalités que vous avez implémentées, un formulaire peut utiliser beaucoup de mémoire, donc les formulaires (ou en général: les objets) ne doivent être créés qu'en cas de besoin et détruits (libérés) dès qu'ils ne sont plus nécessaire.

Les deux «DialogForm» et «OccasionalForm» doivent être supprimés de la liste des «formulaires de création automatique» et déplacés vers la liste des «formulaires disponibles».

Veuillez noter que la stratégie décrite ici est basée sur l'hypothèse que le programme en question est un programme de type «capture» en temps réel. Il peut cependant être facilement adapté aux processus de type batch.

Delphes a essayé de minimiser cela et a sa propre architecture de gestion de la mémoire qui utilise des blocs beaucoup plus petits, mais c'est pratiquement inutile dans l'environnement Windows, car l'allocation de mémoire appartient au système d'exploitation.

Une fois que Windows a alloué un bloc de mémoire à un processus, et que ce processus libère 99,9% de la mémoire, Windows percevra toujours le bloc entier comme étant en cours d'utilisation, même si un seul octet du bloc est réellement utilisé. La bonne nouvelle est que Windows fournit un mécanisme pour résoudre ce problème. Le shell nous fournit une API appelée SetProcessWorkingSetSize. Voici la signature:

Par définition, la fonction SetProcessWorkingSetSize définit les tailles minimales et maximales du jeu de travail pour le processus spécifié.

Cette API est destinée à permettre un réglage de bas niveau des limites de mémoire minimale et maximale pour l'espace d'utilisation de la mémoire du processus. Il a cependant une petite bizarrerie qui est la plus chanceuse.

Si les valeurs minimale et maximale sont définies sur $ FFFFFFFF, l'API réduira temporairement la taille définie à 0, la remplaçant par la mémoire et immédiatement lorsqu'elle rebondit dans la RAM, il aura la quantité minimale de mémoire allouée (tout cela se produit en quelques nanosecondes, donc pour l'utilisateur, cela devrait être imperceptible).

Un appel à cette API ne sera effectué qu'à des intervalles donnés - pas en continu, donc il ne devrait y avoir aucun impact sur les performances.

Maintenant, vérifiez périodiquement le dernier décompte par rapport à «Maintenant» et si la différence entre les deux est supérieure à la période considérée comme une période d'inactivité sûre, ajustez la mémoire.

Décidez maintenant après quelle période vous jugerez le programme inactif. Nous avons décidé de deux minutes dans mon cas, mais vous pouvez choisir n'importe quelle période selon les circonstances.

Adapter cette méthode à de longs délais de traitement ou à des processus batch est assez simple. Normalement, vous aurez une bonne idée du début d'un long processus (par exemple, début d'une lecture de boucle dans des millions d'enregistrements de base de données) et de sa fin (fin de la boucle de lecture de base de données).

Désactivez simplement votre minuteur au début du processus et réactivez-le à la fin du processus.

instagram story viewer