J'exécute un programme C sur le noyau Linux 2.6.16. Je ne pense pas qu'il y ait des fuites de mémoire dans mon programme mais la consommation de mémoire pour le programme reste stable après certaines opérations et ne diminue pas. J'utilise la commande «ps v» pour surveiller la valeur RSS de mon programme.
L'outil Valgrind massif montre qu'une grande partie du tas est allouée par mmap dans mon processus. Mais selon le code, ces allocations auraient dû être libérées une fois les opérations terminées. Est-ce parce que la mémoire libérée est toujours mappée et / ou contribue toujours à la valeur RSS du processus?
Tout aperçu sera très apprécié!
Ci-dessous, un extrait du rapport sur le massif du Valgrind. Remarque J'ai activé l'option --pages-as-heap pour que l'outil massif mesure toutes les mémoires utilisées par le programme.
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
85 701,483,989,262 173,576,192 173,576,192 0 0
86 704,352,949,469 173,367,296 173,367,296 0 0
87 707,582,275,643 173,367,296 173,367,296 0 0
88 710,536,145,814 173,367,296 173,367,296 0 0
100.00% (173,367,296B) (page allocation syscalls) mmap/mremap/brk, --alloc-fns, etc.
->53.40% (92,581,888B) 0x649248B: mmap (in /lib64/tls/libc.so.6)
| ->41.13% (71,303,168B) 0x6446D85: _int_malloc (in /lib64/tls/libc.so.6)
| | ->39.31% (68,157,440B) 0x6448D62: calloc (in /lib64/tls/libc.so.6)
......[my own functions are omitted]
->35.28% (61,157,376B) 0x400F51B: mmap (in /lib64/ld-2.3.3.so)
| ->28.81% (49,954,816B) 0x4004CE8: _dl_map_object_from_fd (in /lib64/ld-2.3.3.so)
| | ->28.81% (49,954,816B) 0x400636B: _dl_map_object (in /lib64/ld-2.3.3.so)
| | ->18.89% (32,755,712B) 0x400AB42: openaux (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x400AF7C: _dl_catch_error (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x4009FCF: _dl_map_object_deps (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x40021FD: dl_main (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x400E7F6: _dl_sysdep_start (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x4001477: _dl_start (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x4000CF6: ??? (in /lib64/ld-2.3.3.so)
| | | ->18.89% (32,755,712B) 0x0: ???
| | | ->18.89% (32,755,712B) 0x7FF0003D5: ???
| | | ->18.89% (32,755,712B) 0x7FF0003E4: ???
| | |
......
munmap
? munmap (2)valgrind
ainsi que/proc/<PID>/maps
?mmap
. Mais maintenant je pense que je comprends: vous appelezmalloc
/calloc
, et ça appellemmap
?Réponses:
La fonction de bibliothèque C
free()
peut, mais n'est pas obligée, renvoyer de la mémoire au noyau.Certaines implémentations de
malloc()
déplacer la frontière entre "tas" et l'espace d'adressage autrement inutilisé (la "rupture du système") via l'sbrk()
appel système, puis distribuent des morceaux plus petits de ces grandes allocations. Sans que chaque petit morceau soit désalloué,free()
il ne peut pas vraiment retourner la mémoire au système d'exploitation.Cette même raison s'applique aux
malloc()
implémentations qui n'utilisent passbrk(2)
, mais peut-être utilisermmap("/dev/zero")
ou quelque chose .. Je ne trouve pas de référence, mais il me semble que l'un ou l'autre des BSD a utilisé demmap()
cette façon pour obtenir des pages de mémoire. Néanmoins,free()
ne peut pas retourner une page au système d'exploitation à moins que chaque sous-allocation soit désallouée par le programme.Certaines
malloc()
implémentations renvoient de la mémoire au système: ChorusOS (?) L'a apparemment fait. Il n'est pas clair s'il a déplacé la rupture du système ou lesmunmap()'ed
pages.Voici un article sur un allocateur de mémoire qui améliore les performances en «abandonnant de manière agressive des pages libres au gestionnaire de mémoire virtuelle». Diaporama pour une présentation de l'allocateur.
la source