free()는 프로세스의 메모리 매핑을 해제합니까?

free()는 프로세스의 메모리 매핑을 해제합니까?

저는 Linux 2.6.16 커널에서 C 프로그램을 실행하고 있습니다. 내 프로그램에 메모리 누수가 있는 것 같지는 않지만 프로그램의 메모리 소비는 안정적으로 유지되고 특정 작업 후에도 감소하지 않습니다. 나는 프로그램의 RSS 값을 모니터링하기 위해 "ps v" 명령을 사용합니다.

valgrind Massif 도구는 내 프로세스의 힙 대부분이 mmap을 통해 할당되었음을 보여줍니다. 그러나 코드에 따르면 이러한 할당은 작업이 완료된 후에 해제되어야 합니다. 해제된 메모리가 여전히 매핑되어 있거나 프로세스의 RSS 값에 계속 기여하고 있기 때문입니까?

어떤 통찰력이라도 대단히 감사하겠습니다!

다음은 valgrind의 플롯 보고서의 일부입니다. 프로그램에서 사용하는 모든 메모리를 측정하기 위해 Massif 도구의 --pages-as-heap 옵션을 설정했습니다.

--------------------------------------------------------------------------------
  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: ???
| |   |
......

답변1

C 라이브러리 함수는 free()커널에 메모리를 반환할 수 있지만 필수는 아닙니다.

일부 구현에서는 malloc()시스템 호출을 통해 "힙"과 기타 사용되지 않은 주소 공간("시스템 인터럽트") 사이의 경계를 이동한 다음 sbrk()이러한 대규모 할당 중 더 작은 부분을 할당합니다. 각각의 작은 부분을 할당 해제하지 않고는 free()실제로 메모리를 운영 체제에 반환할 수 없습니다 .

malloc()을 사용하지 않지만 다른 것을 sbrk(2)사용할 수 있는 구현 에도 동일한 이유가 적용됩니다 . mmap("/dev/zero")참조를 찾을 수 없지만 mmap()메모리 페이지를 얻기 위해 이것을 사용하는 특정 BSD를 기억하는 것 같습니다. 그러나 free()프로그램이 각 하위 할당을 해제하지 않는 한 페이지는 운영 체제로 반환될 수 없습니다.

일부 malloc()구현에서는 시스템에 메모리를 반환합니다.코러스OS(?)분명히 그렇습니다. 시스템 인터럽트나 페이지를 이동했는지는 확실하지 않습니다 munmap()'ed.

이것은 메모리 할당자에 관한 논문입니다."가상 메모리 관리자에 사용 가능한 페이지를 적극적으로 전달"하여 성능을 향상합니다. 프레젠테이션용 슬라이드 쇼할당자 정보.

관련 정보