Je réponds à la balise linux . Ma réponse n'est spécifique qu'à Linux .
Oui, les pages énormes sont plus sujettes à la fragmentation. Il existe deux vues de la mémoire, celle que votre processus obtient (virtuelle) et celle que le noyau gère (réelle). Plus une page est grande, plus il sera difficile de regrouper (et de la conserver) ses voisins, en particulier lorsque votre service s'exécute sur un système qui doit également prendre en charge d'autres qui, par défaut, allouent et écrivent sur beaucoup plus de mémoire qu'eux finissent par utiliser.
Le mappage par le noyau des adresses accordées (réelles) est privé. Il y a une très bonne raison pour laquelle l'espace utilisateur les voit comme le noyau les présente, car le noyau doit pouvoir surcharger sans confondre l'espace utilisateur. Votre processus obtient une belle, contigu « Disneyfied » espace d'adressage où travailler, sans se soucier de ce que le noyau est en fait en train de faire avec cette mémoire dans les coulisses.
La raison pour laquelle vous constatez une dégradation des performances sur des serveurs de longue durée est probablement due au fait que les blocs alloués qui n'ont pas été explicitement verrouillés (par exemple mlock()
/ mlockall()
ou posix_madvise()
) et non modifiés depuis un certain temps ont été paginés , ce qui signifie que votre service dérape sur le disque lorsqu'il doit lire leur. La modification de ce comportement fait de votre processus un mauvais voisin , c'est pourquoi de nombreuses personnes placent leur SGBDR sur un serveur complètement différent de web / php / python / ruby / que ce soit. La seule façon d'y remédier, sainement, est de réduire la concurrence pour les blocs contigus.
La fragmentation n'est vraiment perceptible (dans la plupart des cas) que lorsque la page A est en mémoire et que la page B a été déplacée pour être échangée. Naturellement, le redémarrage de votre service semble `` remédier '' à cela, mais uniquement parce que le noyau n'a pas encore eu l'occasion de consulter le processus '' (maintenant) les blocs nouvellement alloués dans les limites de son ratio de surcharge.
En fait, le redémarrage (disons) de 'apache' sous une charge élevée va probablement envoyer des blocs appartenant à d'autres services directement sur le disque. Alors oui, 'apache' s'améliorerait pendant un court laps de temps, mais 'mysql' pourrait souffrir .. au moins jusqu'à ce que le noyau les fasse souffrir également quand il y a simplement un manque de mémoire physique suffisante.
Ajoutez plus de mémoire ou divisez les malloc()
consommateurs exigeants :) Ce n'est pas seulement la fragmentation que vous devez regarder.
Essayez vmstat
d'obtenir un aperçu de ce qui est réellement stocké où.