O free () não mapeia a memória de um processo?

8

Estou executando um programa em C no kernel do Linux 2.6.16. Eu não acho que há vazamentos de memória no meu programa, no entanto, o consumo de memória para o programa permanece estável após certas operações e não diminui. Eu uso o comando 'ps v' para monitorar o valor RSS do meu programa.

A ferramenta massivo valgrind mostra que uma grande parte do heap é alocada pelo mmap em meu processo. Mas de acordo com o código, essas alocações deveriam ter sido liberadas depois que as operações fossem concluídas. É porque a memória liberada ainda está mapeada e / ou ainda contribui para o valor RSS do processo?

Qualquer informação será muito apreciada!

Abaixo está o recorte do relatório massivo valgrind. Note que eu ativei a opção --pages-as-heap para a 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: ???
| |   |
......
    
por michelle 31.10.2012 / 17:42

1 resposta

5

A função da biblioteca C free() pode, mas não precisa, retornar a memória ao kernel.

Algumas implementações de malloc() movem o limite entre o "heap" eo espaço de endereço não utilizado (a "quebra do sistema") por meio da chamada do sistema sbrk() , distribuindo pedaços menores dessas grandes alocações. Sem obter todas as partes menores desalocadas, free() não pode realmente retornar a memória para o SO.

O mesmo motivo se aplica a malloc() implementações que não usam sbrk(2) , mas talvez use mmap("/dev/zero") ou algo assim. Não consigo encontrar uma referência, mas parece que me lembro de uma ou outra das O BSD usou mmap() para obter páginas de memória. No entanto, free() não pode retornar uma página ao sistema operacional, a menos que cada subalocação seja desalocada pelo programa.

Algumas implementações malloc() retornam memória ao sistema: ChorusOS (?) aparentemente fez. Não está claro se mudou a quebra do sistema ou munmap()'ed páginas.

Aqui está um artigo sobre um alocador de memória que melhora o desempenho "agressivamente desistir de páginas livres para o gerenciador de memória virtual ". Apresentação de slides para uma palestra sobre o alocador.

    
por 31.10.2012 / 20:17

Tags