Тонкости malloc и free

У меня есть два связанных вопроса, поэтому я задаю их в этой единственной ветке.

Q1) Как я могу подтвердить, очищает ли моя ОС несвободную память (выделенную с помощью malloc) автоматически при завершении программы? Я использую 32-разрядную версию Ubuntu 11.04 с gcc-4.5.2

Согласно странице руководства Стивена Саммита, здесь, «Освобождение неиспользуемой памяти (malloc'ed) - хорошая идея , но это не обязательно. Когда ваша программа завершает работу, любая память, которая была выделена, но не освобождена, должна быть автоматически освобождена. Если ваш компьютер каким-то образом `` потерял '' память только потому, что ваша программа забыла освободить ее, это будет означать проблема или недостаток в вашей операционной системе. "

Q2) Предположим, foo.c блокирует B-байтовую память. Позже foo.c освобождает эти B-байтовые ячейки памяти и возвращает их в ОС. Теперь мой вопрос: могут ли эти ОПРЕДЕЛЕННЫЕ B-байты ячеек памяти перераспределить для foo.c (ОС) в текущем экземпляре ИЛИ эти B-байты не могут быть выделены для foo .c, пока его текущий экземпляр не прекратит работу?

ИЗМЕНИТЬ: я бы рекомендовал всем, кто читает мой вопрос, прочитать ответ на аналогичный вопрос здесь и здесь. Оба ответа подробно объясняют взаимодействие и работу malloc () и free () без использования очень эзотерических терминов. Чтобы понять РАЗНИЦУ между инструментами управления памятью, используемыми ядром (например, brk (), mmap ()), и инструментами, используемыми C-компилятором (например, malloc (), free ()), это НЕОБХОДИМО ПРОЧИТАТЬ.


person Abhinav    schedule 25.04.2012    source источник


Ответы (4)


Когда процесс завершается либо по сигналу завершения, например, SIGSEGV или с помощью системного вызова _exit (2) (который также вызывается, когда возвращаясь из main), все ресурсы процесса освобождаются ядром. В частности, адресное пространство процесса, включая память кучи (выделенную с помощью mmap (2) ( или, возможно, sbrk(2)) выпущен системный вызов (используемый malloc библиотечной функцией).

Конечно, функция библиотеки free либо (часто) делает освободившуюся зону памяти повторно используемой для дальнейших вызовов malloc, либо (иногда для больших зон памяти) высвобождает некоторый большой кусок памяти для ядра, используя, например, munmap(2) системный вызов.

Чтобы узнать больше о карте памяти процесса 1234, последовательно прочитайте псевдо-файл /proc/1234/maps (или /proc/self/maps изнутри процесса). Файловая система / proc является предпочтительным способом запроса ядра о процессах. (есть еще /proc/self/statm и /proc/self/smaps и много другого интересного).

Подробное поведение free и malloc зависит от реализации. Вы должны рассматривать malloc как способ получить память из кучи, а free как способ сказать, что ранее использовавшаяся зона malloc-ed бесполезна, и система (то есть стандартная библиотека C + ядро) может делать с ней все, что захочет.

Используйте valgrind для поиска ошибок утечки памяти. Вы также можете рассмотреть возможность использования консервативного сборщика мусора Боэма, то есть использовать GC_malloc вместо malloc и не беспокойтесь об освобождении памяти вручную.

person Basile Starynkevitch    schedule 25.04.2012
comment
Спасибо за удовлетворительный ответ. Я полагаю, что каталог / proc / foo / будет существовать, пока запущена программа foo.c. Правильно? Итак, в таком случае, как мне получить соответствующий файл карт? Хотя я действительно проверил файл карт некоторых работающих pid (например, хром), и он предоставил мне кучу потрясающей информации. Я поражен. :) - person Abhinav; 25.04.2012
comment
Я не уверен, что понимаю ваш вопрос (не забывайте, что исполняемые файлы и процессы не совпадают; данная программа имеет один исполняемый файл, например /bin/bash для вашей оболочки, но может выполняться в нескольких процессах). /proc/1234/ существует только до тех пор, пока существует процесс 1234. (Это псевдо-файл, не на диске, поэтому его можно быстро прочитать). Внутри этого процесса /proc/self/ является символической ссылкой на него. - person Basile Starynkevitch; 25.04.2012
comment
Поднимите палец вверх за ссылки valgrind и Boehm. - person Abhinav; 25.04.2012

Большинство современных ОС будут освобождать выделенную память, поэтому вам не нужно об этом беспокоиться.
ОС не понимает, произошла ли утечка памяти в вашем приложении / программе, она просто восстанавливает то, что было выделено процессу, после завершения процесса.

Да, освобожденную память можно повторно использовать (при необходимости), и повторное использование может происходить в том же экземпляре.

person Alok Save    schedule 25.04.2012
comment
Есть ли какой-либо практический способ подтвердить это, скажем, с помощью тестового программного обеспечения, которое я могу сделать или могу напрямую использовать? - person Abhinav; 25.04.2012
comment
@Abhinav: К счастью, эти накладные расходы не нужны. Вам просто нужно сослаться на документацию вашей целевой ОС, и она должна документировать поведение. - person Alok Save; 25.04.2012
comment
@Abhinav, подтверждаю, какая часть? Вы не можете подтвердить, что ОС освобождает память процесса без инструментария ОС, что замедлит ее управление памятью, и вам будет очень трудно расшифровать ее в современной ОС с унифицированным кешем страниц. Для повторного использования памяти процесса посетите valgrind.org. - person geekosaur; 25.04.2012

Q1. Вам просто нужно предположить, что операционная система ведет себя правильно.

Q2. Нет причин, по которым байты нельзя перераспределить в foo.c, это просто зависит от того, как работают процедуры выделения памяти.

person Nick    schedule 25.04.2012

Q1) Я не уверен, как вы можете подтвердить. Тем не менее, что касается второго абзаца, считается хорошим стилем всегда освобождать всю память, которую вы выделяете. Хорошее объяснение этому можно найти здесь: Что ДЕЙСТВИТЕЛЬНО происходит, когда вы не освободить после malloc?.

Q2) Определенно; эти байты обычно перераспределяются первыми (в зависимости от реализации malloc). Подробное объяснение см .: Как работают malloc () и free ()? .

person rainbowsprinkles    schedule 25.04.2012
comment
Существует мнение, что вы не должны освобождать память при выходе из программы - аргумент состоит в том, что это похоже на уборку дома, из которого вы выезжаете, который будет снесен - это пустая трата времени и усилий. Я не совсем согласен, но не могу винить аргумент :) - person mattnz; 25.04.2012