Почему моя программа на c не освобождает память как следует? - PullRequest
2 голосов
/ 15 января 2009

Я сделал программу на c и хотел посмотреть, сколько памяти она использует, и заметил, что использование памяти увеличивается при обычном использовании (во время запуска она использует около 250 Кб, а теперь она составляет 1,5 Мб). afaik, я освободил всю неиспользованную память и через несколько часов приложение использует меньше памяти. Возможно ли, что освобожденная память просто переходит из «активной» памяти в «проводную» или что-то еще, поэтому она освобождается, когда требуется свободное место? Кстати. моя машина работает на Mac OS X, если это важно.

Ответы [ 6 ]

9 голосов
/ 15 января 2009

Как вы определяете использование памяти? Вы пытались использовать valgrind для обнаружения потенциальных утечек памяти? Это действительно легко. Просто запустите ваше приложение с valgrind, запустите его и посмотрите на хорошо структурированный вывод.

7 голосов
/ 15 января 2009

Если вы смотрите на использование памяти в ОС, вы, вероятно, увидите это поведение. Освобожденная память не возвращается автоматически в ОС, но обычно остается в процессе и может быть позже размещена. То, что вы видите, обычно является высшим знаком использования памяти.

Как предложил Конрад Рудольф, используйте что-то, что исследует память изнутри процесса, чтобы найти ссылки на память.

6 голосов
/ 15 января 2009

Библиотека C обычно не возвращает «небольшие» выделения ОС. Вместо этого он сохраняет память в следующий раз, когда вы используете malloc.

Однако многие библиотеки C выпускают большие блоки, поэтому вы можете попробовать сделать malloc в несколько мегабайт и затем освободить его.

2 голосов
/ 15 января 2009

Я согласен с тем, что все уже сказали, но я хочу добавить лишь несколько поясняющих замечаний, касающихся os x:

Во-первых, операционная система фактически выделяет память, используя vm_allocate, которая выделяет целые страницы за раз. Поскольку с этим связаны издержки, как заявляли другие, библиотека C не просто освобождает страницу, когда вы возвращаете память через free(3). В частности, если на странице памяти есть другие выделения, она не будет освобождена. В настоящее время страницы памяти имеют размер 4096 байт в mac os x. Количество байтов на странице может быть определено программно с помощью sysctl(2) или, более просто, с помощью getpagesize(2). Вы можете использовать эту информацию для оптимизации использования памяти.

Во-вторых, приложения пользовательского пространства не связывают память. Обычно ядро ​​связывает память для критических структур данных. Проводная память - это, по сути, память, которая никогда не может быть выгружена и никогда не вызовет ошибку страницы. Если по какой-либо причине на странице с проводной памятью возникнет сбой страницы, ядро ​​запаникует, и ваш компьютер выйдет из строя. Если ваше приложение увеличивает проводную память вашего компьютера на заметную величину, это очень плохой признак. Как правило, это означает, что ваше приложение делает что-то, что значительно увеличивает структуры данных ядра, например, выделяет и не пожинает сотни потоков дочерних процессов. (конечно, это общее утверждение ... в некоторых случаях ожидается такой рост, например, при разработке виртуального хоста или чего-то подобного).

2 голосов
/ 15 января 2009

В OSX вы сможете использовать MallocDebug.app, если вы установили Инструменты разработчика из OSX (так как у вас могут возникнуть проблемы с поиском порта valgrind для OSX).

/ Developer / Applications / PerformanceTools / MallocDebug.app

1 голос
/ 15 января 2009

В дополнение к тому, что другие уже написали:

malloc () выделяет большие фрагменты из ОС и разбивает их на более мелкие части по мере того, как вы используете malloc (). При освобождении () кусок сначала попадает в список свободных для быстрого повторного использования другим malloc, если размер подходит. В это время он может быть объединен с другим свободным элементом, чтобы сформировать большие свободные блоки, чтобы избежать фрагментации (там существует целая куча различных алгоритмов, от freeLists до фрагментов двоичного размера, до хэширования и т. Когда освобождаются фрагменты, чтобы можно было объединить несколько фрагментов, обычно это делает free (), но иногда фрагменты остаются, в зависимости от размера и порядка malloc () и free (). Кроме того, только когда большой такой свободный блок был создан, он (иногда) возвращается в ОС как блок. Но обычно malloc () хранит вещи в своем кармане, в зависимости от соотношения между выделенным и свободным (многие эвристики, а иногда и опции компиляции или флагов часто доступны).

Обратите внимание, что не существует ОДНОГО malloc / free algotrithm. Существует целая куча разных реализаций (и литературы). Зависит от системы, ОС и библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...