Mémoire
Un article de Haypo.
Version du 24 juillet 2007 à 21:21 (modifier) Haypo (Discuter | Contributions) (→Mémoire et Xorg) ← Différence précédente |
Version du 21 août 2007 à 12:13 (modifier) (défaire) Haypo (Discuter | Contributions) (→Pile) Différence suivante → |
||
Ligne 116 : | Ligne 116 : | ||
Pour détecter le dépassement de la pile (« notifiée » par un signal SIGSEGV envoyé par le noyau), on peut utiliser le programme : [http://www.haypocalc.com/perso/prog/stack.c stack.c]. | Pour détecter le dépassement de la pile (« notifiée » par un signal SIGSEGV envoyé par le noyau), on peut utiliser le programme : [http://www.haypocalc.com/perso/prog/stack.c stack.c]. | ||
- | On peut utiliser une pile dédié aux gestionnaires de signal avec | + | On peut utiliser une pile dédié aux gestionnaires de signal avec signaltstack(). |
On peut limiter la taille de la pile d'un thread avec pthread_attr_setstacksize(). | On peut limiter la taille de la pile d'un thread avec pthread_attr_setstacksize(). |
Version du 21 août 2007 à 12:13
Retour aux articles de programmation
Notes sur l'utilisation de la mémoire dans un programme.
Sommaire |
État actuel
Savoir lire l'état de la mémoire
Lorsqu'on fait un top, on a des fois des sueurs froides en interprétant mal les différentes colonnes.
$ top ... (je tape M pour trier par utilisation de la mémoire) ... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 15404 haypo 15 0 73240 40m 22m S 0.3 8.2 0:35.20 konqueror 22370 root 15 0 359m 22m 2800 S 0.0 4.6 9:12.06 Xorg 12098 haypo 15 0 89944 19m 7740 S 0.0 3.8 0:18.36 gajim.py 14355 haypo 15 0 40836 11m 7388 S 0.0 2.3 0:30.56 gvim
Colonnes concernant la mémoire :
- VIRT : Taille de la mémoire virtuelle. Notion assez lointaine de l'utilisation mémoire. En gros, c'est la taille totale que pourrait atteindre un programme s'il utilisait toute la mémoire. Or cette valeur est très loin de l'utilisation réelle.
- RES : Mémoire « résidente ». C'est cette valeur qu'il faut lire en premier quand on veut savoir quel programme utilise toute la mémoire. C'est la mémoire qu'un programme utilise réelle et juste pour son usage personnel.
- SHR : Mémoire « partagée ». C'est la mémoire utilisée partagées avec les autres processus.
« RSS. Taille de l’ensemble résident : nombre de pages dont le processus dispose en mémoire réelle, moins 3 pour des raisons administratives. Il s’agit juste des pages contenant les espaces de code, donnée et pile. Ceci n’inclut ni les pages en attente de chargement ni celles qui ont été swappées. »
getrusage()
La fonction getrusage() renseigne l'utilisation des ressources du processus courant. Champs renseignant sur l'état de la mémoire :
- ru_maxrss : Taille résidente maximale
- ru_ixrss : Taille de mémoire partagée
- ru_idrss : Taille des données non partagées
- ru_isrss : Taille de pile
- ru_minflt : Demandes de pages
- ru_majflt : Nombre de fautes de pages
- ru_nswap : Nombre de swaps
Les valeurs sont exprimées en nombre de pages. Il faut lire la taille d'une page pour avoir la valeur en octets.
free
Commande free :
$ free total used free shared buffers cached Mem: 506488 356632 149856 0 18892 155056 -/+ buffers/cache: 182684 323804 Swap: 1485972 163940 1322032
/proc/self/statm
$ cat /proc/self/statm 689 144 121 4 0 61 0
Signification des colonnes :
- Taille totale du programme (en pages)
- Taille résidente du programme (en pages)
- Nombre de pages partagées
- Nombre de pages de code
- Nombre de pages de bibliothèques
- Nombre de pages de donnée ou de pile
- Nombre de pages touchées (dirty pages)
Source : (en) Red Hat Enterprise Linux 3: Reference Guide (Chapter 5. The proc File System).
/proc/meminfo
État de la mémoire physique. Lignes intéressantes :
$ cat /proc/meminfo MemTotal: 506488 kB MemFree: 82396 kB Buffers: 36448 kB Cached: 173540 kB SwapTotal: 1485972 kB SwapFree: 1324976 kB
/proc/self/status
Le fichier /proc/self/status contient des lignes intéressantes :
$ grep Vm /proc/self/status VmPeak: 2828 kB VmSize: 2828 kB VmLck: 0 kB VmHWM: 744 kB VmRSS: 744 kB VmData: 156 kB VmStk: 84 kB VmExe: 92 kB VmLib: 1304 kB VmPTE: 12 kB
Les différentes lignes :
* VmPeak : Valeur maximale de la mémoire virtuelle depuis la naissance du processus * VmSize : Taille de la mémoire virtuelle * VmLck : ??? * VmHWM : ??? * VmRSS : Mémoire « résidente » * VmData : Taille de la mémoire (des données) en lecture seule * VmStk : Taille de la pile * VmExe : Taille du code * VmLib : Mémoire des bibliothèques partagées * VmPTE : ???
Mémoire et Xorg
Il faut utiliser le programme xrestop pour lire la répartition en mémoire des pixmaps par processus.
Lisez aussi X.org myths de Stéphane Marchesin.
Pile
Sous Linux, la taille a une taille d'environ 8 Mo.
On peut changer la taille de la pile initiale lors de la compilation, via la commande : « ld --stack=... ».
Pour détecter le dépassement de la pile (« notifiée » par un signal SIGSEGV envoyé par le noyau), on peut utiliser le programme : stack.c.
On peut utiliser une pile dédié aux gestionnaires de signal avec signaltstack().
On peut limiter la taille de la pile d'un thread avec pthread_attr_setstacksize().
gcc a plusiers options relatives à la gestion de la pile:
- « -fstack-check »
- « -mmax-stack-frame=n » : Avertissement si une fonction utilise plus de n octets de pile
- « -fstack-limit-register=reg »
- «-fstack-limit-symbol=sym »
- « -fno-stack-limit » : Pas de limlite de pile
- (dans le code) « __attribute__ ((sp_switch ("alt_stack"))) » indique qu'on utilise la pile de la variable alt_stack (void *alt_stack = malloc(...))
La fonction alloca() alloue de la mémoire sur la pile : en fait, c'est simplement un changement de valeur d'ESP (sur i386). gcc a la fonction __builtin_alloca(). La fonction alloca() a un comportement indéfini lorsque la limite de la mémoire est dépassée, il ne faut donc pas l'utiliser. Voir :
- alloca and reliable stack-overflow detection in glibc functions
- Re: glibc glob_filename() recurse call stack overflow
Python
- Module gc
- re.purge() libère les caches
- Memory debugging in Python -- fighting the GC : Billet présentant en détail le fonctionnement de gc
- Wikipédia : Ramasse-miettes
Surveiller l'utilisation de la mémoire : Heapy et (plus vieux et n'est plus maintenu) pysizer.
pymalloc
Le gestionnaire de mémoire internet de Python 2.3 et 2.4, pymalloc, est bogué. Il ne libère jamais la mémoire : lisez le billet d'Evan Jones pour en savoir plus. Evan Jones a justement corrigé ce bug et son travail a été intégré dans Python 2.5 : lisez l'annonce d'Evan Jones et l'annonce de Tim Peters sur la liste de diffusion python-dev. Tim Peters a repris le travail d'Evan Jones, l'a corrigé et l'a commité dans le trunk de Python.
setrlimit
Sous Linux, seul setrlimit(RLIMIT_AS) fonctionne. setrlimit(RLIMIT_RSS) et setrlimit(RLIMIT_DATA) ne fonctionnent pas. Lire un email d'Alan Cox à ce sujet.