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 actuelle (21 août 2007 à 21:09) (modifier) (défaire) Haypo (Discuter | Contributions) (→Pile) |
||
(3 révisions intermédiaires masquées) | |||
Ligne 101 : | Ligne 101 : | ||
* VmLib : Mémoire des bibliothèques partagées | * VmLib : Mémoire des bibliothèques partagées | ||
* VmPTE : ??? | * VmPTE : ??? | ||
+ | |||
+ | == ELC == | ||
+ | |||
+ | Matt Mackall prépare des patchs pour le noyau Linux permettant d'avoir une meilleure idée de la mémoire utilisée par une application : http://lwn.net/Articles/230975/ | ||
== Mémoire et Xorg == | == Mémoire et Xorg == | ||
Ligne 114 : | Ligne 118 : | ||
On peut changer la taille de la pile initiale lors de la compilation, via la commande : « ld --stack=... ». | 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 : | + | Pour détecter le dépassement de la pile (« notifiée » par un signal SIGSEGV envoyé par le noyau), on peut utiliser le programme : {{HaypoSVN svnweb link|misc/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(). | ||
Ligne 122 : | Ligne 126 : | ||
[[gcc]] a plusiers options relatives à la gestion de la pile: | [[gcc]] a plusiers options relatives à la gestion de la pile: | ||
* « -fstack-check » | * « -fstack-check » | ||
- | * « -mmax-stack-frame=n » : Avertissement si une fonction utilise plus de ''n'' octets de pile | + | * « -mmax-stack-frame=n » : Avertissement si une fonction utilise plus de ''n'' octets de pile <= ne fonctionne que pour l'architecture CRIS |
* « -fstack-limit-register=reg » | * « -fstack-limit-register=reg » | ||
* «-fstack-limit-symbol=sym » | * «-fstack-limit-symbol=sym » |
Version actuelle
Retour aux articles de programmation
Notes sur l'utilisation de la mémoire dans un programme.
Sommaire |
[modifier] État actuel
[modifier] 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. »
[modifier] 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.
[modifier] 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
[modifier] /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).
[modifier] /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
[modifier] /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 : ???
[modifier] ELC
Matt Mackall prépare des patchs pour le noyau Linux permettant d'avoir une meilleure idée de la mémoire utilisée par une application : http://lwn.net/Articles/230975/
[modifier] 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.
[modifier] 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 <= ne fonctionne que pour l'architecture CRIS
- « -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
[modifier] 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.
[modifier] 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.
[modifier] 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.