Estoy ejecutando un programa C en el kernel de Linux 2.6.16. No creo que haya pérdidas de memoria en mi programa, sin embargo, el consumo de memoria para el programa permanece estable después de ciertas operaciones y no disminuye. Uso el comando 'ps v' para monitorear el valor RSS de mi programa.
La herramienta valgrind massif muestra que mmap asigna una gran parte del montón en mi proceso. Pero de acuerdo con el código, esas asignaciones deberían haberse liberado después de que se realicen las operaciones. ¿Es porque la memoria liberada todavía está asignada y / o todavía contribuye al valor RSS del proceso?
Cualquier idea será muy apreciada!
A continuación se muestra el recorte del informe valgrind macizo. Tenga en cuenta que he activado la opción --pages-as-heap para la herramienta de macizo para medir todas las memorias utilizadas por el programa.
--------------------------------------------------------------------------------
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
y también/proc/<PID>/maps
?mmap
. Pero ahora creo que entiendo: ¿estás llamandomalloc
/calloc
y está llamandommap
?Respuestas:
La función de biblioteca C
free()
puede, pero no es necesario, devolver la memoria al núcleo.Algunas implementaciones de
malloc()
mover el límite entre el "montón" y el espacio de direcciones no utilizado (el "corte del sistema") a través de lasbrk()
llamada al sistema, luego reparten piezas más pequeñas de esas grandes asignaciones. Sin desasignar cada pieza más pequeña,free()
realmente no puedo devolver la memoria al sistema operativo.Esa misma razón se aplica a las
malloc()
implementaciones que no usansbrk(2)
, pero tal vez usanmmap("/dev/zero")
o algo así. No puedo encontrar una referencia, pero parece recordar que uno u otro de los BSD usammap()
esa manera para obtener páginas de memoria. Sin embargo,free()
no se puede devolver una página al sistema operativo a menos que el programa desasigne todas las subasignaciones.Algunas
malloc()
implementaciones devuelven memoria al sistema: ChorusOS (?) Aparentemente lo hizo. No está claro si movió el sistema roto, o lasmunmap()'ed
páginas.Aquí hay un documento sobre un asignador de memoria que mejora el rendimiento al "renunciar agresivamente a páginas gratuitas para el administrador de memoria virtual". Presentación de diapositivas para una charla sobre el asignador.
fuente