Ich führe ein C-Programm unter Linux 2.6.16 aus. Ich glaube nicht, dass es Speicherlecks in meinem Programm gibt, aber der Speicherverbrauch für das Programm bleibt nach bestimmten Vorgängen stabil und nimmt nicht ab. Ich verwende den Befehl 'ps v', um den RSS-Wert meines Programms zu überwachen.
Das Valgrind-Massiv-Tool zeigt an, dass ein großer Teil des Heaps in meinem Prozess von mmap zugewiesen wird. Gemäß dem Code sollten diese Zuordnungen jedoch nach Abschluss der Vorgänge freigegeben worden sein. Liegt es daran, dass der freigegebene Speicher noch zugeordnet ist und / oder immer noch zum RSS-Wert des Prozesses beiträgt?
Jeder Einblick wird sehr geschätzt!
Unten ist der Ausschnitt aus dem Valgrind-Massivbericht. Hinweis Ich habe die Option --pages-as-heap für das Massiv-Tool aktiviert, um alle vom Programm verwendeten Speicher zu messen.
--------------------------------------------------------------------------------
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
sowie bereitstellen/proc/<PID>/maps
?mmap
. Aber jetzt denke ich zu verstehen: Du rufstmalloc
/calloc
an und es ruftmmap
?Antworten:
Die C-Library-Funktion
free()
kann, muss aber nicht, Speicher an den Kernel zurückgeben.Einige Implementierungen
malloc()
verschieben die Grenze zwischen "Heap" und ansonsten nicht verwendetem Adressraum (der "Systembruch") über densbrk()
Systemaufruf und verteilen dann kleinere Teile dieser großen Zuordnungen. Ohne die Zuweisung jedes kleineren Teilsfree()
kann der Speicher nicht wirklich an das Betriebssystem zurückgegeben werden.Der gleiche Grund gilt für
malloc()
Implementierungen, die nicht verwendet werdensbrk(2)
, aber möglicherweise verwendenmmap("/dev/zero")
oder so. Ich kann keine Referenz finden, aber ich scheine mich daran zu erinnern, dass die eine oder andere BSD aufmmap()
diese Weise verwendet wurde, um Speicherseiten abzurufen. Esfree()
kann jedoch keine Seite an das Betriebssystem zurückgegeben werden, es sei denn, jede Unterzuweisung wird vom Programm freigegeben.Einige
malloc()
Implementierungen geben Speicher an das System zurück: ChorusOS (?) Hat dies anscheinend getan. Es ist nicht klar, ob der Systembruch oder diemunmap()'ed
Seiten verschoben wurden .Hier ist ein Artikel über einen Speicherzuweiser , der die Leistung verbessert, indem er "freie Seiten aggressiv an den virtuellen Speichermanager abgibt". Diashow für einen Vortrag über den Allokator.
quelle