[Linux] Gestion de la RAM et du Swap

Libération de la RAM utilisée pour le cache

Par défaut, Linux a tendance à utiliser toute la RAM pour accélérer ses opérations, et notamment pour y placer en cache ses données.

On peut donc arriver facilement à des situations où la RAM est utilisée à 90% ou plus, alors que les traitements n'en prennent que la moitié.

Par exemple, sur un serveur disposant de 7,5 Go de mémoire, la commande free -m donne :

[root@~]# free -m
             total       used       free     shared    buffers     cached
Mem:          7873       7289        583          0        251       4272
-/+ buffers/cache:       2765       5107
Swap:         4095         70       4025

Il semble effectivement y avoir plus de 7 Go de RAM utilisée, dont plus de 4 Go pour le cache (buffers et cache), ce que nous donne la dernière colonne cached. On peut forcer l'O.S. à vider ses caches, via la commande :

[root@~]# sync; echo 3 > /proc/sys/vm/drop_caches

Une fois cette opération effectuée, on regarde l'utilisation mémoire :

[root@~]# free -m
             total       used       free     shared    buffers     cached
Mem:          7873       4264       3608          0          1       1625
-/+ buffers/cache:       2637       5236
Swap:         4095         70       4025

Après la manipulation, on n'utilise plus qu'un peu plus de 4 Go de RAM, ce qui permet de respirer un peu...

Utilisation du swap

Le swap est une mémoire physique "virtuelle", souvent installée sous Linux dans une partition indépendante. Une partie du disque dur est réservée à cette mémoire virtuelle qui viendra soulager le système en cas de surcharge. La partition a un type bien spécifique, que l'on peut voir en lançant la commande fdisk

[root@~]# fdisk -l
Disque /dev/mapper/vmvg-vm_debian6 : 8388 Mo, 8388608000 octets
255 têtes, 63 secteurs/piste, 1019 cylindres, total 16384000 secteurs
Unités = secteurs de 1 * 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 4096 octets
taille d'E/S (minimale / optimale) : 4096 octets / 4096 octets
Identifiant de disque : 0x000210a6

               Périphérique Amorce  Début        Fin      Blocs     Id  Système
/dev/mapper/vmvg-vm_debian6p1   *        2048    15611903     7804928   83  Linux
/dev/mapper/vmvg-vm_debian6p2        15613950    16381951      384001    5  Étendue
La partition 2 ne débute pas sur une frontière de cylindre physique.
/dev/mapper/vmvg-vm_debian6p5        15613952    16381951      384000   82  partition d'échange Linux / Solaris

Sur les machines actuelles disposant de plusieurs Go de RAM, l'utilisation de la Swap est de moins en moins fréquente, et heureusement car les accès disques étant beaucoup moins rapides que les accès mémoire, si le système commence à "swapper", les performances dégringolent généralement de manière abrupte.

Utilisation globale

Plusieurs commandes permettent de connaître l'utilisation du swap, parmi lesquelles top ou free.
Avec le commande top, on regarde les données dans le haut de l'écran :

top - 14:43:57 up 72 days,  5:27,  1 user,  load average: 0.01, 0.01, 0.00
Tasks: 220 total,   1 running, 218 sleeping,   0 stopped,   1 zombie
Cpu(s):  6.3%us,  0.6%sy,  1.1%ni, 89.0%id,  2.9%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:   8062108k total,  4389280k used,  3672828k free,     7220k buffers
Swap:  4194296k total,    74252k used,  4120044k free,  1683072k cached

Avec la commande free, on se concentre sur la dernière ligne, intitulée Swap :

free
             total       used       free     shared    buffers     cached
Mem:       8062108    4389116    3672992          0       7552    1682920
-/+ buffers/cache:    2698644    5363464
Swap:      4194296      74456    4119840

Par défaut la valeur est en kb, identique à ce qui est donné par la commande top.

Ceci permet d'avoir une première idée de l'utilisation du swap. Mais il est également intéressant de savoir quel process utilise le swap.

Utilisation par process

Les fichiers /proc/PID/status donnent des informations intéressantes sur les processus en cours d'exécution.
On peut notamment y trouver la quantité de mémoire virtuelle utilisée.

Le paramètre est différent selon le type de distribution.

  • Debian & co : colonne VmSwap
  • Red Hat & co : colonne VmSwap ou VmSize selon la version

Par exemple, sur une Ubuntu, on a bien les informations VmSize et VmSwap :

# cat /proc/10247/status
Name:	firefox
State:	S (sleeping)
Tgid:	10247
Pid:	10247
PPid:	3021
.../...
VmPeak:	 1730196 kB
VmSize:	 1636532 kB
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	  758972 kB
VmRSS:	  617804 kB
VmData:	  964084 kB
VmStk:	     256 kB
VmExe:	      92 kB
VmLib:	  129060 kB
VmPTE:	    2876 kB
VmSwap:	       0 kB
Threads:	40
.../...

Sur une Red Hat 6.2, on dispose également du détail :

# cat /proc/6688/status
Name:	ibmslapd
State:	S (sleeping)
Tgid:	6688
Pid:	6688
PPid:	1
.../...
VmPeak:	 1791200 kB
VmSize:	 1650840 kB
VmLck:	       0 kB
VmHWM:	  217560 kB
VmRSS:	  217560 kB
VmData:	 1380708 kB
VmStk:	      88 kB
VmExe:	     792 kB
VmLib:	   43640 kB
VmPTE:	     488 kB
VmSwap:	       0 kB
Threads:	21
.../...

Sur une Red Hat 5.8, les données sont plus restreintes, on n'a pas l'information sur le Swap :

# cat /proc/4136/status
Name:	ibmslapd
State:	S (sleeping)
SleepAVG:	98%
Tgid:	4136
Pid:	4136
PPid:	1
.../...
VmPeak:	 4121736 kB
VmSize:	 4056684 kB
VmLck:	       0 kB
VmHWM:	 3466892 kB
VmRSS:	 3465728 kB
VmData:	 3829212 kB
VmStk:	      88 kB
VmExe:	     792 kB
VmLib:	   99972 kB
VmPTE:	    7184 kB
StaBrk:	1d665000 kB
Brk:	32f28000 kB
StaStk:	7fffeedd4340 kB
Threads:	21
.../...

 

Pour avoir la liste des processus qui utilisent le swap, triés par taille croissante, on peut utiliser la suite de commandes, selon la distribution :

Debian ou Red Hat 6.x :

for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB  | sort -k 3 -n

Ces commandes donnent le nom du process, son PID et la taille mémoire en swap. Par exemple :

.../...
upstart-socket- 1046 208 kB
dnsmasq 1523 220 kB
polkitd 1052 260 kB
modem-manager 1018 552 kB
NetworkManager 1044 564 kB
smbd 945 808 kB
colord 1468 828 kB
smbd 1112 860 kB
whoopsie 1329 900 kB
libvirtd 1354 1176 kB



RedHat EL 5.x

for file in /proc/*/status ; do awk '/Tgid|VmSize|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -n

Ces commandes donnent le nom du process, son PID et la taille mémoire virtuelle (swap + reserved). Exemple sur une RHEL 5.8 :

.../...db2syscr 3844 606824 kB
db2syscr 3846 606824 kB
db2syscr 3847 606824 kB
db2fmp 5575 616528 kB
db2fmp 7349 634096 kB
db2fmp 3863 765116 kB
java 13612 857012 kB
db2syscr 3841 866876 kB
ibmslapd 4136 4056684 kB
java 4546 5540972 kB
db2sysc 3843 6206912 kB
java 5570 8865344 kB

Par rapport à la commande top, on retrouve la taille indiquée dans la colonne VIRT, ici 836MB pour notre process java :

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                
 4136 idsldap   15   0 3961m 3.3g 9268 S  0.0 14.1   9:39.30 ibmslapd                                                               
 4546 wasadm    18   0 5411m 3.0g  59m S  1.0 12.8 154:11.71 java                                                                   
 3843 idsldap   25   0 6061m 2.7g 2.7g S  0.0 11.6  31:36.82 db2sysc                                                                
 5570 root      22   0 8657m 2.1g 7024 S  0.0  9.1   4:21.82 java                                                                   
13612 explitdi  25   0  836m 300m 7048 S  0.0  1.2   5:06.06 java 

 

Autant dire que si le swap est fortement sollicité, il faut envisager de faire un peu de tuning des processus, ou d'augmenter la RAM sur celle-ci.

Catégorie
Tag