Gestion de la Mémoire

La gestion de la mémoire dans Visual FoxPro n’est pas moins complexe. Il y a eu deux versions de FoxPro 2.x, une version 16-bit et une 32-bit utilisant une extension du DOS. L’extension du DOS changea elle même ente 2.0 et 2.6. Il existe pour les applications DOS différents types de mémoire qui sont tous régis par différents gestionnaires de mémoire. Il existe les modes concurrents XMS et EMS. Il y a HIMEM qui étend la mémoire conventionnelle et DPMI, l’interface Mode Protége du DOS, qui est encore supportée par Windows. Tous ces types de mémoire ont été pris en compte par les différentes versions de FoxPro, et du code en reste présent dans Visual FoxPro, quoiqu’il ne soit plus utilisé. Par exemple, la plupart des fonctions de contrôle de la mémoire, non documentées entre SYS(1001) et SYS(1016) sont toujours opérationnelles. Microsoft ajouta d’autres modèles de mémoire dépendant des versions de Windows. Même dans la version 32-bits actuelle de Windows plusieurs types de mémoire cohabitent. (Mémoire physique, fichiers d’échange–swap, locale, globale, virtuelle, paginée, etc.)

Au dessus de la mémoire physique et des différents modèles de mémoire mis en œuvre par le système d’exploitation, VFP gère son propre système. VFP distingue 5 types de mémoire: piles, tampons hors écrans, handle pool, page pool, et fichiers temporaires. La pile est utilisée pour les processus temporaires, et n’est pas significative pour le développeur. La pile apparaît généralement dans des conditions d’erreurs telles que "insufficient stack space" (Espace de pile insuffisant Erreur 1308). Seuls les développeurs C/C++ écrivant un FLL ont a se préoccuper de la pile.

Le groupe d’handles, “Handle Pool”, est la mémoire utilisée pour différents objets VFP tels les fenêtres, les menus, les classes, les objets, les curseurs, les sessions etc. Ce pool n’a aucune limite arbitraire et ne dépend que de la quantité de mémoire disponible. Visual FoxPro met en œuvre un modèle astucieux prohibant l’accès direct à la mémoire, rendant ainsi portable VFP sur différentes plateformes (Windows, Unix, Mac).

De nombreuses données doivent être gardées en mémoire. Cela inclu variables, menus, fenêtres, chaînes mais aussi définitions de classe, formulaires, et plus encore. Chaque fois que Visual FoxPro requiert de la mémoire, le gestionnaire de mémoire est appelé avec la taille de bloc de mémoire demandé. Plutôt que de retourner une adresse, il renvoie un gestionnaire de mémoire (memory handle). Cela peut s’assimiler à une sorte de clé primaire. A chaque fois qu’un programme veut accéder à cette mémoire, Il doit auparavant verrouiller la mémoire un peu comme un enregistrement doit l’être. L’adresse peut ensuite être déterminée par une fonction interne. Lorsque cet accès mémoire est terminé, le code doit déverrouiller le handle, de manière similaire au déverrouillage d’un enregistrement.

La finalité de ces verrous est cependant différente de ceux concernant les enregistrements. Il ne s’agit pas de prévenir des accès concurrents à la mémoire, mais d’éviter la dispersion des blocs. Lorsque des blocs sont constamment alloués et libérés, au fil du temps la mémoire devient fragmentée. Cela arrive de la même manière aux disques durs lors de la création et de l’annulation de fichiers. Après un certain temps, cela peut conduire à une situation ou il y a suffisamment de mémoire disponible, mais ou aucun bloc n’est assez grand pour contenir la donnée requise. Cela serait fatal à un système de base de données qui devrait tourner sans cesse pour des jours ou des semaines, et ou une telle situation conduirait au crash.
Pour éviter cela, le ramasse miette (garbage collection) est susceptible de déplacer les blocs mémoire. En interne, Visual FoxPro exécute une sorte de défragmentation lorsqu’il est inactif (idle). Mais la défragmentation n’a pas été la seule raison de mettre en œuvre ce modèle. La mémoire n’est pas en outre toujours disponible en lecture. Par exemple, la mémoire étendue DOS devait être transposée en mémoire conventionnelle avant que les versions étendues de FoxPro puissent y accéder. Lorsqu’un handle FoxPro est verrouillé, les fonctions de gestion de FoxPro peuvent s’assurer que ce bloc mémoire est immédiatement disponible en lecture pour le programme appelant. Après le déverrouillage, FoxPro peut réaffecter au bloc sa position originale.

Une partie du Handle Pool est visible aux développeurs par la commande LIST MEMORY mais pas tous les handles. Visual FoxPro fait aussi un usage intensif des handles en interne. Toutes le fenêtres d’édition sont par exemple de tels handles. Ainsi il est possible d’utiliser ACTIVATE WINDOW non seulement pour nos propres fenêtres, mais pour toutes les fenêtres FoxPro, y compris les barres d’outils. Avec Visual Foxpro, le Handle Pool n’est limité que par la mémoire physique disponible, ou par la mémoire virtuelle.
La fonction SYS(1001) retourne la taille maximale du Handle Pool. La fonction, (non documentée) SYS(1011) retourne le nombre de handles alloués. Cette fonction se doit de retourner la même valeur avant, et après l’appel d’une fonction. Toute autre valeur indique une fuite de mémoire. SYS(1016) renvoie la taille de la partie du Handle Pool déjà allouée. SYS(1104) initie manuellement un garbage collection. Cette dernière fonction est officiellement documentée depuis VFP 7.0. Toutes ces fonctions renvoient des valeurs variables lorsqu’elles sont exécutées dans la fenêtre de commande, car cette fenêtre de commande initie constamment un état d’attente et donc une purge des tampons (garbage collection). Certaines fonctions filtrent en interne les handles utilisés, d’autres non. Quoiqu’il en soit, ces fonctions sont de bons indicateurs de l’utilisation de la mémoire.
Pratiquement, tout ce qui n’est pas temporaire est mémorisé quelque part dans le Handle Pool cela inclus les transactions et les modifications dans un tampon mémoire en attente de validation par une commande TABLEUPDATE().

Le groupe de pages (Page Pool) est la zone mémoire contrôlée par SYS(3050). Visual FoxPro y stocke les images crées par Rushmore et l’utilise pour le cache des tables et index. Cette partie de la mémoire est essentiellement responsable de la vitesse remarquable de Visual FoxPro Tout ce qui est lu du disque est mis là en cache pour une utilisation ultérieure. La taille maximum de cette zone mémoire peut être contrôlée en adaptant la mémoire allouée par Visual FoxPro aux zones tampon de premier plan et d'arrière-plan. La zone tampon de premier plan représente celle qui permet à Visual FoxPro de fonctionner au premier plan en tant qu'application actuellement active. La zone tampon d'arrière-plan représente la mémoire qui permet à Visual FoxPro de fonctionner à l'arrière-plan lorsqu'une autre application est au premier plan. Cela signifie qu’il est possible d’indiquer à Visual FoxPro d’utiliser plus ou moins de mémoire si l’utilisateur travaille sur l’application ou non. Cette mémoire n’est pas allouée immédiatement, mais suivant nécessité. Une très grande valeur peut donc être attribuée sans avoir à craindre qu’elle soit immédiatement utilisée.
SYS(3050) essaye d’allouer la mémoire de Windows qui ne soit pas “swappée” vers le disque. Il n’y a toutefois aucune garantie. Il y aura un effet sensible sur la performance si Visual Foxpro essaye d’allouer de la mémoire pour des caches qui ne puisse exister que par une mémoire virtuelle sur le disque dur. Réduire la valeur de SYS(3050) libère immédiatement toute mémoire superflue. La valeur minima étant 256 KB (pas MB) le code suivant peut être utilisé pour libérer la mémoire au-delà de 256 KB:

lcMemory = Sys(3050,1)
Sys(3050,1,1)
Sys(3050,1,Val(lcMemory))

Pour autant, avoir le contrôle complet sur le Page Pool n’assure pas que ce soit vrai pour l’utilisation de la mémoire. Si Visual FoxPro pense devoir utiliser plus de mémoire, par exemple pour stocker une image d’optimisation RushMore, il n’hésitera pas à créer un fichier temporaire si le Page Pool n’est pas assez vaste. FoxPro continuera à s’exécuter, même si la valeur spécifiée de SYS(3050) est trop faible, peut être à la même vitesse, mais peut être plus lentement voire plus rapidement. Cela dépendra du type de mémoire assignée à Visual FoxPro et de la rapidité du support concerné. Celui utilisé par Windows pour la mémoire virtuelle, ou celui utilisé par Visual FoxPro pour stocker les fichiers temporaires? Windows pouvant aussi utiliser un cache pour les fichiers temporaires, la rapidité de l’application pourrait s’avérer soudainement plus rapide.

Le répertoire utilisé pour les fichiers temporaires dépend des réglages sauvegardés dans le registre: la clé TMPFILES=… (pas TEMPFILES!) et de différents réglages de Windows. Parfois, toutefois, Visual FoxPro est susceptible de discrètement permuter vers un autre répertoire. Cela semble causé par nombre de facteurs. Dans tous les cas il est possible de vérifier la valeur courante de SYS(2023) qui peut différer du répertoire normalement utilisé par Windows pour les fichiers temporaires. La pire situation serait celle où Visual FoxPro utiliserait le répertoire Home de l’utilisateur, ou le répertoire des programmes, ceux-ci se trouvant souvent sur le serveur. Pour s’assurer de la destination réelle des fichiers temporaires, un curseur test peut être créé dont la position sera vérifiée par la fonction DBF(). Car même si un curseur est généralement créé dans le répertoire indiqué par SYS(2023) il se peut que ce ne soit pas toujours être le cas.