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

これはメモリアロケータに関する論文です。「仮想メモリマネージャに利用可能なページを積極的に渡す」ことで、パフォーマンスが向上します。 プレゼンテーション用のスライドショーアロケータ情報。

おすすめ記事