Estou executando um programa C no kernel do Linux 2.6.16. Eu não acho que haja vazamentos de memória no meu programa, no entanto, o consumo de memória para o programa permanece estável após determinadas operações e não diminui. Eu uso o comando 'ps v' para monitorar o valor RSS do meu programa.
A ferramenta valgrind massif mostra que uma grande parte do heap é alocada pelo mmap no meu processo. Mas, de acordo com o código, essas alocações deveriam ter sido liberadas após a conclusão das operações. É porque a memória liberada ainda está mapeada e / ou ainda contribui para o valor RSS do processo?
Qualquer visão será muito apreciada!
Abaixo está o recorte do relatório maciço valgrind. Observe que ativei a opção --pages-as-heap da ferramenta massif para medir todas as memórias usadas pelo 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
e também/proc/<PID>/maps
?mmap
. Mas agora acho que entendo: você está ligandomalloc
/calloc
e está ligandommap
?Respostas:
A função da biblioteca C
free()
pode, mas não precisa, retornar memória ao kernel.Algumas implementações
malloc()
movem o limite entre "heap" e espaço de endereço não utilizado (a "quebra do sistema") por meio dasbrk()
chamada do sistema e distribuem partes menores dessas grandes alocações. Sem que todas as partes menores sejam desalocadas,free()
não é possível retornar a memória ao sistema operacional.O mesmo motivo se aplica a
malloc()
implementações que não usamsbrk(2)
, mas talvez usammmap("/dev/zero")
ou algo assim. Não consigo encontrar uma referência, mas me lembro que um ou outro BSD usoummap()
essa maneira para obter páginas de memória. No entanto,free()
não é possível retornar uma página ao sistema operacional, a menos que todas as subalocações sejam desalocadas pelo programa.Algumas
malloc()
implementações retornam memória ao sistema: o ChorusOS (?) Aparentemente retornou . Não está claro se ele mudou a quebra do sistema ou asmunmap()'ed
páginas.Aqui está um artigo sobre um alocador de memória que melhora o desempenho "abrindo agressivamente páginas gratuitas para o gerenciador de memória virtual". Apresentação de slides para uma palestra sobre o alocador.
fonte