Egalement appelé disque de swap ou swap tout court, un périphérique de swap (swap device) est un espace de stockage brut confié aux bons soins du kernel pour y stocker, éventuellement, ceraines pages mémoires pour le cas où cette ressource se faisait rare. Il fût un temps, que certains ne peuvent pas connaître mais qui en ont tout de même entendu parler, où l’on définissait le volume de cet espace par rapport à la taille de la mémoire physique (RAM). Depuis une petite décennie, on a tous dit que c’était bien fini, même des fois on en rit. Vous découvrirez un peu plus bas que finalement cet espace n’est pas si inutile que ça.
Non, ce n’est pas une insulte, c’est juste l’espace mémoire auquel le kernel accède au travers de ses contrôleurs mémoires, bus, MMU, etc. Bref, en règle générale ça se matérialise sous forme de barrettes, et surtout c’est là qu’est chargé tout ce dont vos process ont besoin pour travailler; dès que vous demandez la lecture d’un fichier par exemple, une page du fichier est chargé en mémoire (voire plus avec les phénomènes de cache), et les octets demandés vous sont renvoyés. Ceci est vrai évidemment pour les fichiers exécutables; pour les faire tourner, le code doit également être chargé en mémoire. En résumé, chaque fourmi besogneuse de la machine va utiliser cet espace.
La freelist est la quantité effective de mémoire physique disponible à un instant. Lorsqu’un process demande l’allocation d’une zone mémoire, cette zone est réservée Lorsqu’une page de cette mémoire n’est plus utilisé (par exemple vous avez fermé le fichier ou encore votre process est décédé -RIP- ), le kernel va la tagguer comme disponible pour un utilisation ultérieure. L’ensemble de la mémoire non utilisé ou plus utilisé constitue la freelist.
Aussi connu sous le nom de VM ou carrément de Swap, la Mémoire Virtuelle est un agrégat de tout ce qui est alouable, que ce soit en RAM ou sur disque. La VM brute correspond donc à RAM + SWAP-DEVICE. A cette VM brute il faut soustraire quelques Mo par-ci, par là pour comprendre à quel chiffre les commandes comme swap -s ou vmstat se réfèrent. En fait, la formule magique pour calculer la VM sur Solaris est RAM + SWAP-DEVICE - (OBP + HyperViseur + Non_Swappable_Kernel_Pages)
Si quelqu’un a besoin de s’allouer de l’espace et que la freelist est insuffisante, le kernel va tenter de libérer des pages :
Pour libérer ces espaces, soit on peut resynchroniser avec un espace disque déjà alloué (cas des fichiers par exemple), soit l’existence des données est purement mémoire (cas d’une partie de la zone utilisée par les process). Dans ce dernier cas, le kernel va utiliser les périphériques de swap pour sortir ces pages de la mémoire physique (page-out). Un process dont les éléments vitaux sont évacuées sur le périphérique de swap est dit /swappé (swap-out).
L’un des procédés de communication inter-processus défini par System V (ipcs) est le partage de zone mémoire. Ce procédé a été optimisé dans Solaris, à l’attention notamment des éditeurs de SGBDR. Les segments d’ISM, contrairement aux shared-mem classiques (shm), sont verrouillées à la création. Les avantages de ce verrouillage :
L’ISM a les inconvénients de l’un de ses avantages : son verrouillage permanent interdit tout redimensionnement, obligeant les applications à s’arrêter et redémarrer lorsqu’elle souhaite augmenter la taille de leur segment de mémoire partagée (SGA Oracle par exemple), et interdisant toute velléité de retrait à chaud d’une carte système sur laquelle ces segments seraient installés (DR -Dynamic Reconfiguration- des systèmes SunFire et autre Mx000 qui permettent d’arrêter et de retirer à chaud une carte système -System Board- même si nécessaire en déplaçant le kernel -et ça il n’y a que Solaris qui sait le faire avec sa fameuse quiescence-).
La DISM répond à ces besoins en permettant :
Une demande d’allocation de mémoire (que ce soit un mmap() ou un malloc() qui fait appel à brk() ) ne va pas immédiatement faire diminuer la freelist.
Le kernel va diminuer l’espace disponible de la VM, en incrémentant l’espace réservé.
Ce n’est que lorsqu’une page est réellement modifiée, que la taille de cette page va changer de compteur...de réservé, elle va passer dans le camp de alloué; et si elle est alloué, elle vient forcément diminuer la freelist.
On voit déjà que le fameux périphérique de swap n’est pas si anodin qu’il n’y parait, puisque lorsque je fait une demande d’allocation de mémoire, cette allocation tape dans la VM de façon indifférencié. Ce n’est qu’à l’utilisation réelle de cette zone que la différence RAM versus SWAP-DEV va jouer.
Pour donner un exemple plus précis et assez contemporain, si vous lancez 20 machines Java avec l’option -Xms256m, chacune de ces machines va faire une demande d’allocation de 256 Mo, soit au total une demande de 5 Go de ressource. Supposons que le code que vous activez via ces machines Java sont des serveurs qui se mettent en attente d’activation distante. Tant que personne ne les activent réellement, on peut raisonnablement penser que l’utilisation réelle des 5 Go est de quelques centaines de Mo. Si vous avez de l’espace disponible dans votre périphérique de swap, le fait que ces serveurs soient lancés, mais pas actifs, ne pénalisent personne. Dans le cas inverse, ces serveurs inactifs consomment réellement 5 Go.
Oui, je sais. Il n’est nullement obligatoire d’affecter un espace disque de swap pour démarrer une machine Solaris. Je sais également qu’une machine qui commence à swaper sur disque des process est à priori en très mauvaise posture.
Mais j’ose imaginer qu’après avoir lu les paragraphes précédent, vous serez d’accord avec moi pour dire que ce serait dommage, voire idiot.
Que ce soit sur un projet ou sur un container, l’utilisation de capping mémoire va entraîner de l’extraction de la RAM de certaines ressources peu utilisées, et ceci avant même que la machine ne soit désespérée. Ceci dépend des attributs de limitation (de capping) et de la configuration de rcapd.
Pour la faire court, le capping mémoire va permettre d’anticiper la crise en libérant doucement ce qui n’est effectivement que peu utilisé, mais il risque pour cela d’avoir besoin d’espace de swap sur disque.
Difficile néanmoins d’établir une formule de calcul...ce n’est ici qu’une justification supplémentaire au fait de provisionner de l’espace de swap sur disque.
Prenez en compte l’application qui utilise de la DISM va forcément verrouiller au moins une partie de cette mémoire partagée. Il est difficile de prévoir le taux de verrouillage effectif, il est donc raisonnable d’octroyer sur disque un espace égal à l’utilisation de DISM qui sera faite. Pensez également qu’il est fort possible que l’administrateur de l’application en question (en général une SGBDR) augmente au fil du temps la taille de cette zone, prévoyez donc un peu de marge.
Cette fois il faut prendre en compte le type d’utilisation de la machine.
Une machine de production sera, à priori, peut enclin à héberger des processus réservant de la mémoire sans l’utiliser. On ignorera sans doute ce point.
Une machine de qualification ou de recette sera plus sensible à ce genre de fluctuations, au delta près de la manière dont elle sera gérée : est-ce qu’elle est mise à disposition d’une seule équipe, d’un seul projet à un instant T, ou partagée entre plusieurs projets qui n’y travaille pas forcément en simultané pure ? La règle ici serait de provisionner un espace correct permettant à des process de faire ce type de réservation, sans utilisation effective, sans déranger.
Je ne pourrais que trop vous conseiller en environnement critique de dédier un périphérique particulier pour faire cet office; si vous ne pouvez/voulez pas, prévoyez que votre espace disque soit d’au moins 50% votre RAM.
Cela n’engage que moi, mais voici quelques conseils qui pourront vous aide à prendre votre propre décision en fonction de votre environnement.
# swap -s total: 16620016k bytes allocated + 8178424k reserved = 24798440k used, 14190768k available
# vmstat 2 2 kthr memory page disk faults cpu r b w swap free re mf pi po fr de sr m1 m1 m1 m2 in sy cs us sy id 0 0 0 9377880 7663624 564 3252 1023 1 1 0 0 15 8 8 1 2845 12258 6980 4 7 89 0 0 0 14162568 2507560 0 27 0 0 0 0 0 0 0 0 0 810 4752 5463 3 4 94
C’est la colonne ISMATTCH de la commande ipcs -Zbim ou ipcs -ZAm qui vous donne le nombre d’attachement en mode ISM du segment (SHM_SHARE_MMU ou SHM_PAGEABLE).
# ipcs -Zim IPC status from <running system> as of Wed Mar 11 17:34:56 CET 2009 T ID KEY MODE OWNER GROUP ISMATTCH ZONE Shared Memory: m 33554529 0x41008e6b --rw-rw-rw- webservd webservd 0 zweb m 251658331 0x4100800e --rw-rw-rw- root root 0 zweb m 251658330 0x41008cc2 --rw-rw-rw- root root 0 zweb m 1711276098 0x741cc1a4 --rw-rw-rw- root root 0 zoracle m 117440577 0x741cc1a3 --rw-rw-rw- root root 0 zoracle m 117440576 0x741cc1a2 --rw-rw-rw- root root 0 zoracle m 234881087 0x741cc1a1 --rw-rw-rw- root root 0 zoracle m 2113929278 0x741cc1a0 --rw-rw-rw- root root 0 zoracle m 218103860 0x1483b388 --rw-rw---- orause olalalala 9 zoracle m 201326685 0xbd45e16c --rw-rw---- orause olalalala 12 zoracle m 2046820397 0x7faa22a8 --rw-rw---- orause olalalala 13 zoracle m 1358954511 0x900fbad4 --rw-rw---- orause olalalala 11 zoracle m 1526726667 0xc9ff9a44 --rw-rw---- orause olalalala 11 zoracle m 184549379 0x2da62e70 --rw-rw---- orause olalalala 10 zoracle m 318767105 0x67960de0 --rw-rw---- orause olalalala 10 zoracle
Pour calculer la taille totale de ce type de segment :
# ipcs -ZAm | awk 'NR>1&&$16>0{s+=$10} END{print "total=", s/1024}'
total= 10149912
Ca peut être long, pas de panique !
# echo "::memstat" | mdb -k Page Summary Pages MB %Tot ------------ ---------------- ---------------- ---- Kernel 974712 7614 29% Anon 2012652 15723 59% Exec and libs 16454 128 0% Page cache 37295 291 1% Free (cachelist) 74369 581 2% Free (freelist) 271852 2123 8% Total 3387334 26463 Physical 3332228 26033
Le support de Sun France qui m’a longuement aidé à mettre tous ces éléments ensembles (et spéciale dédicace à François !).
— Nicolas Dorfsman Mars 2009 —