Les problématiques de performances dégradées sont régulièrement remontées à notre attention dans le cadre de notre métier de support. Parmi elles, les consommations excessives de certains types de pool mémoire que nous appelons entre nous les 2019 et les 2020.
Ce bulletin va donc traiter de ces problématiques.
Ici nous allons nous focaliser uniquement sur l'architecture 32Bits.
Par défaut, sous Windows 32bits chaque processus utilisateur peut avoir jusqu'à 2Go d'espace d'adressage privé et le système prend les 2 autres restants. Ci-dessous un schéma représentant l'espace d'adressage virtuel en 32Bits.
Il est possible d'allouer plus de mémoire en mode user via l'option /3GB dans le boot.ini. Cette option n'est exploitable que pour des applications qui sont à même d'utiliser de l'espace mémoire au delà des 2Go, c'est à dire celle compilées pour avoir dans leur fichier image le flag IMAGE_FILE_LARGE_ADDRESS_AWARE. Ce fût le cas par exemple, pour des applications de base de données entre autres.
L'utilisation de l'option /3GB ne doit pas être prise à la légère. Le fait d'utiliser cette option, va allouer 3Go en mode User et réduire de 1Go le mode kernel, donc notre kernel n'a plus qu'un seul Giga pour son utilisation. Comme vous le comprendrez cela peut avoir un impact sur les performances.
Dans l'espace Kernel nous avons entre autre 2 espaces mémoire appelés Paged Pool et Non Paged Pool.
Le Paged Pool est la région de la mémoire virtuelle de l’espace système qui peut être déchargée vers le fichier de pagination puis rechargée en mémoire physique.
Les pilotes de périphérique qui n’ont pas besoin d’accéder à la mémoire depuis le niveau DPC/Dispatch ou supérieur peuvent utiliser le pool paginé, qui est accessible depuis n’importe quel contexte de processus.
Le Non Paged Pool se compose de plages d’adresses virtuelles qui sont assurées de résider en permanence en mémoire physique et auxquelles on peut donc accéder en permanence (depuis n’importe quel IRQL et contexte de processus) sans risquer d’avoir une faute de page.
Les pilotes faisant appel à ces espaces mémoire utilisent les fonctions comme ExAllocatePoolWithTag et ExFreePoolWithTag.
Ces 2 espaces mémoire ne sont pas illimités : En fonction de la taille de la mémoire physique et de l'utilisation où pas du /3GB la quantité de Paged Pool et Non Paged Pool peut être différente.
Ci-dessous un tableau indiquant approximativement la quantité de Paged Pool et Non Paged Pool dans Windows 2000 :
Ci-dessous un tableau indiquant approximativement la quantité de Paged Pool et Non Paged Pool Windows 2003 32Bit :
Si vous voulez connaître la taille maximale de Non Paged Pool ou Paged Pool disponible sur votre serveur (taille calculée au démarrage du serveur), suivre la procédure suivante :
Il arrive parfois que vous ayez un serveur qui devient de plus en plus lent jusqu'au hang total du serveur lui même, vous obligeant à procéder à un redémarrage électrique du serveur.
Fréquemment ce genre de problème est lié à un manque de ressources. Nous allons voir ici, le manque de ressources lié au Paged Pool ou Non Paged Pool.
Suite au redémarrage du serveur, le fonctionnement redeviens normal, jusqu'à la prochaine apparition des problèmes de lenteur et/ou de hang. Il peut se passer plusieurs heures, plusieurs jours ou plusieurs semaines avant la réapparition des symptômes.
Généralement si vous regardez dans le journal Système vous devriez trouver des erreurs de source Srv et comme Event ID 2019 ou 2020. Les 2019 correspondent à un manque de Non Paged Pool et les 2020 à un manque de Paged Pool.
Event ID 2019
Event Type: Error Event Source: Srv Event Category: None Event ID: 2019
Event Type: Error
Event Source: Srv
Event Category: None
Event ID: 2019
Description: The server was unable to allocate from the system NonPaged pool because the pool was empty.
Event ID 2020
Event Type: Error Event Source: Srv Event Category: None Description: The server was unable to allocate from the system paged pool because the pool was empty.
Description: The server was unable to allocate from the system paged pool because the pool was empty.
Ce manque de Paged Pool ou Non Paged Pool est souvent lié à une fuite mémoire (memory leak).
C'est le Service Serveur (Srv.sys) qui logue ces erreurs. Dans de rare cas il se peut que le Service Server ne puisse pas générer ces évents, toutefois cela ne veut pas dire que ce ne soit pas un problème avec les Paged Pool ou Non Paged Pool.
Lorsque vous avez des symptômes de lenteur qui apparaissent dans le temps avec l'un des 2 évènements ID cité ci-dessus, le plan d'action à mettre en place est le suivant :
Perfmon
Memsnap (fournis dans les Support Tools se trouvant sur le CD d'installation de Windows 2003)
Planifier l'exécution de Memsnap
Lorsque le problème se reproduit, vous allez analyser le fichier de log Perfmon généré.
Dans ce log Perfmon, vous devez regarder dans l'objet Memory (Mémoire) les compteurs:
Vous devez mettre à l'échelle ces compteurs afin de voir leur progression dans le temps.
Dans le cas d'une fuite mémoire, vous devriez voir une consommation croissante sans relâchement de la mémoire Paged Pool ou Non Paged Pool, la consommation peut être linéaire, par escalier ou brutal.
Ci-dessous un exemple de fuite mémoire, ici en blanc et concernant le Non Paged Pool:
Après avoir identifié la fuite mémoire, vous pouvez regarder dans l'objet Processus (Process) les compteurs Pool Non Paged Bytes et/ou Pool Paged Bytes afin de voir si l'un des processus est à l'origine de la fuite mémoire. Si vous ne trouvez pas un processus qui semble effectuer une fuite mémoire ou si c'est le processus System, vous devez analyser le log Memsnap afin d'identifier quel driver est à l'origine de la fuite mémoire.
Memsnap va permettre de prendre des "clichés" de l'utilisation de l'espace mémoire du Paged Pool et Non Paged Pool.
Lorsqu'un composant fait une demande d'allocation de cette mémoire, un tag est positionné afin de pouvoir suivre les demandes d'allocations. Ce tag est comme une balise, qui nous permettra d'identifier le driver.
Le tag est sur 4 Bytes, chaque drivers a en principe un tag qui lui est propre.
Ci-dessous un petit extrait du fichier Memsnap
Dans le log Memsnap, vous devez regarder quel tag consomme de façon croissante du Paged Pool ou Non Paged Pool.
Une fois que vous avez identifié le Tag, vous pouvez rechercher quel driver utilise ce tag.
Pour cela, via un cmd, positionnez-vous dans le répertoire Windows\System32\Drivers puis exécuter la commande suivante:
C:\WINDOWS\system32\drivers>Findstr /M "XXXX" *.sys (XXXX correspond au tag)
Ensuite en fonction du résultat, contacter l'éditeur de ce driver afin de lui remonter le problème et obtenir un correctif ou mettre à jour vous même le drivers vers une version plus récente.
Dans un prochain bulletin, nous parlerons des problèmes de lenteurs et de hang liés à un manque de Paged Pool et Non Paged Pool sans qu’il y ait de fuite mémoire (memory leak).
Philippe
Windows Core Senior Support Escalation Engineer