Почему мне нужно освобождать динамическую память вручную? [Дубликат]

Есть карты Саши, с которыми мне пришлось написать: -)

http://www.maryanovsky.com/sasha/maps/

Написанная в GWT, поддерживает все настольные браузеры, iOS и Android. Вам нужно будет предоставить свои собственные плитки (или найти того, кто позволит вам использовать их).

77
задан Andreas Grech 6 February 2010 в 16:37
поделиться

8 ответов

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

Опираясь на это, это плохая практика, и лучше ее явно освободить. Проблема заключается не только в том, что ваш код выглядит плохо. Вы можете решить, хотите ли вы интегрировать свою небольшую программу в более крупную и длинную. Затем через некоторое время вам придется часами отслеживать утечки памяти. Использование функции операционной системы также делает код менее портативным.

92
ответ дан Yacoby 28 August 2018 в 06:42
поделиться
  • 1
    Однажды я столкнулся с win98 на встроенной платформе и, основываясь на этом опыте, могу сказать, что НЕ освобождает память, когда программы закрываются. – San Jacinto 6 February 2010 в 16:44
  • 2
    @Ken Это был пример. Кроме того, существует линия между YAGNI и неаккуратным кодированием. Это не освобождает ресурсы. Принцип YAGNI также должен применяться к функциям, а не к коду, который делает работу программы корректной. (И не освобождение памяти - это ошибка). – Yacoby 6 February 2010 в 16:53
  • 3
    +1: самое важное, что следует учитывать, - это то, что управление памятью происходит так, как Yacoby вполне корректно заявляет: & quot; особенность операционной системы & quot; . Если я не ошибаюсь, язык программирования не определяет, что происходит до или после выполнения программы. – D.Shawley 6 February 2010 в 16:57
  • 4
    Освобождение памяти вручную занимает больше времени, принимает больше кода и вводит возможность ошибок (скажите, что вы никогда не видели ошибку в коде освобождения!). Это не «небрежный». преднамеренно опустить что-то, что ухудшается во всех отношениях для вашего конкретного случая использования. Если вы не собираетесь запускать его на какой-то древней / крошечной системе, которая не может освобождать страницы после завершения процесса или интегрировать ее в более крупную программу (YAGNI), это выглядит как чистый убыток для меня. Я знаю, что это вредит эго программиста, чтобы думать о том, чтобы не очищать его самостоятельно, но каким практическим способом это на самом деле лучше? – Ken 6 February 2010 в 17:56
  • 5
    Любой, кто предлагает утечку памяти на SO, должен быть лишен всех репутаций и значков – Ulterior 17 May 2012 в 22:38

Что здесь происходит ( в современной ОС ), так это то, что ваша программа запускается внутри собственного «процесса». Это объект операционной системы, который наделен своим собственным адресным пространством, файловыми дескрипторами и т. Д. Ваши вызовы malloc выделяют память из «кучи» или нераспределенных страниц памяти, которые назначены вашему процессу.

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

Это моральный эквивалент, когда вы закончили использовать свой ноутбук и хотите отдать его другу, вы не потрудитесь индивидуально удалять каждый файл. Вы просто отформатируете жесткий диск.

Все это сказало, как отмечают все остальные ответчики, полагаясь на это не очень хорошая практика:

  1. Вы всегда должны программировать забота о ресурсах, а также в C, что также означает память. Вы можете вставить свой код в библиотеку, или он может работать намного дольше, чем вы ожидаете.
  2. Некоторые ОС (более старые и, возможно, некоторые современные встроенные) могут не поддерживать такие жесткие границы процесса, и ваши распределения могут повлиять на адресные пространства других пользователей.
5
ответ дан Ben Zotto 28 August 2018 в 06:42
поделиться

Это зависит от того, операционные системы, как правило, очищают его для вас, но если вы работаете, например, встраиваемое программное обеспечение, оно может не быть выпущено.

Просто убедитесь, что вы освободили его, он может сэкономить вам много времени, когда вы захотите интегрировать его в большой проект.

2
ответ дан Charles 28 August 2018 в 06:42
поделиться

Да, операционная система освобождает всю память, когда процесс завершается.

2
ответ дан Draemon 28 August 2018 в 06:42
поделиться
  • 1
    Я не понимаю, почему это было приостановлено. Память malloc'ed будет выпущена, когда процесс замирает (определение wikipedia malloc так говорит) – Arve 6 February 2010 в 17:13
  • 2
    Википедия не является руководством для каждой ОС. Большинство современных ОС вернут память, но не все (и особенно не все старые). Добавьте к этому, malloc может только пообещать, что C будет делать с памятью; по дизайну, C не гарантирует многое из того, что касается поведения вне самой C. Если приложение неожиданно погибает, любые обещания, сделанные в библиотеке времени выполнения, являются недействительными, так как они больше не живы, чтобы соответствовать им. – cHao 23 July 2012 в 02:20

В целом, современные операционные системы общего назначения очищают после прекращенных процессов. Это необходимо, потому что альтернатива заключается в том, что система теряет ресурсы с течением времени и требует перезагрузки из-за плохо написанных программ или просто имеет редко встречающиеся ошибки, которые утечки ресурсов.

Наличие вашей программы явно освобождает ее ресурсы в любом случае может быть хорошей практикой по разным причинам, например:

  • Если у вас есть дополнительные ресурсы, которые не очищены ОС при выходе, например временные файлы или любой тип изменяет на состояние внешнего ресурса, тогда вам понадобится код для работы со всеми этими вещами при выходе, и это часто элегантно сочетается с освобождением памяти.
  • ] Если ваша программа начинает иметь более продолжительный срок службы, вам не нужно, чтобы только способ освобождения памяти для выхода. Например, вы можете конвертировать свою программу в сервер (демон), который продолжает работать при обработке многих запросов для отдельных единиц работы, или ваша программа может стать небольшой частью более крупной программы.

Однако, здесь есть причина, чтобы пропустить освобождение памяти: эффективное завершение работы. Например, предположим, что ваше приложение содержит большой кеш в памяти. Если он выходит, он проходит через всю структуру кэша и освобождает его по одному фрагменту за раз, что не приносит никакой пользы и тратит ресурсы. В частности, рассмотрим случай, когда страницы памяти, содержащие ваш кеш, были заменены на диск операционной системой; прогуливаясь по структуре и освобождая ее, вы сразу возвращаете все эти страницы в память , теряя значительное время и энергию без реальной выгоды и, возможно, даже заставляя другие программы в системе

Как пример, существуют высокопроизводительные серверы, которые работают, создавая процесс для каждого запроса, а затем завершая его завершение; таким образом, им даже не нужно отслеживать выделение памяти , и никогда вообще не делать освобождение или сборку мусора, поскольку все просто возвращается в свободную память операционной системы в конце процесса. (То же самое можно сделать в процессе с использованием специализированного распределителя памяти, но требует очень тщательного программирования, по сути дела, создавая собственное понятие «легкие процессы» в процессе ОС.)

33
ответ дан Kevin Reid 28 August 2018 в 06:42
поделиться

Да. ОС очищает ресурсы. Ну ... старые версии NetWare этого не сделали.

Изменить: Как отметил Сан-Хасинто, есть, конечно, системы (помимо NetWare), которые этого не делают. Даже в отброшенных программах я стараюсь освободить все ресурсы, чтобы сохранить привычку.

4
ответ дан Mark Wilkins 28 August 2018 в 06:42
поделиться
  • 1
    Я не спускаюсь, но это довольно опасный пост для потомков. DOS по-прежнему используется на многих встроенных платформах, и я СЕРЬЕЗНО сомневаюсь, что он делает очистку памяти для вас. Широкое обобщение неверно. – San Jacinto 6 February 2010 в 16:54
  • 2
    @San Jacinto: Это хороший момент. Вот почему я сделал ссылку NetWare, но, вероятно, мог бы использовать пояснения. Я немного его отредактирую. – Mark Wilkins 6 February 2010 в 17:15
  • 3
    @San DOS не является многозадачной ОС - когда заканчивается программа DOS (исключая TSR), вся память доступна для следующей загружаемой программы. – user 6 February 2010 в 17:22
  • 4
    @Neil спасибо за напоминание, но я имел в виду TSR-подобную программу, которая запускалась бы при возникновении события, как это часто используется для встроенных систем. Тем не менее, спасибо за ваш опыт и разъяснения, где я потерпел неудачу :) – San Jacinto 6 February 2010 в 17:32

Мои извинения за публикацию так долго после последнего сообщения в этом потоке.

Еще одна точка. Не все программы делают это изящными выходами. Сбой и ctrl-C и т. Д. Приведет к неконтролируемому завершению работы программы. Если ваша ОС не освобождает вашу кучу, очистите стек, удалите статические переменные и т. Д., Вы в конечном итоге разрушите вашу систему от утечек памяти или еще хуже.

Интересно, что в этом случае сбои / перерывы в Ubuntu, и я подозреваю, что у всех других современных ОС есть проблемы с «обработанными» ресурсами. Сокеты, файлы, устройства и т. д. могут оставаться «открытыми», когда программа заканчивается / сбой. Также неплохо закрыть что-либо с «ручкой», или «дескриптор» как часть вашей очистки до изящного выхода.

В настоящее время я разрабатываю программу, которая сильно использует сокеты. Когда я застрял в зависании, мне нужно вывести ctrl-c, таким образом, скручивая мои сокеты.Я добавил std :: vector, чтобы собрать список всех открытых сокетов и обработчик sigaction, который ловит sigint и sigterm. Обработчик просматривает список и закрывает сокеты. Я планирую сделать аналогичную процедуру очистки для использовать перед броском, что приведет к преждевременному прекращению.

Кто-нибудь хочет прокомментировать этот проект?

7
ответ дан mk12 28 August 2018 в 06:42
поделиться
  • 1
    Я рад, что вы это сказали, потому что у меня была программа, которая оставила ресурсы сокетов вокруг, и наша система Ubuntu нуждалась в перезагрузке каждые две недели, или память начала работать, и есть много памяти. Я не уверен, что системные ресурсы срываются, если вы забыли их очистить. – octopusgrabbus 8 July 2012 в 22:29
  • 2
    Stackoverflow - это не форум; не существует ничего неправильно при ответе на старый вопрос. meta.stackexchange.com/questions/20524/reviving-old-questions – mk12 16 August 2012 в 02:45

Я думаю, что прямое освобождение лучше. Неопределенное поведение - худшее, поэтому, если у вас есть доступ, пока он еще определен в вашем процессе, сделайте это, есть много веских причин, которые люди дали для него.

Что касается того, где, или я, что в W98 реальный вопрос был «когда» (я не видел, чтобы сообщение подчеркивало это). Небольшая программа шаблонов (для входа MIDI SysEx, используя различные пространства malloc'd) освободила бы память в бит WM_DESTROY от WndProc, но когда я пересадил это в большую программу, он разбился при выходе. Я предположил, что это означает, что я пытался освободить то, что ОС уже освободило во время большей очистки. Если я сделал это в WM_CLOSE, а затем вызвал DestroyWindow (), все это работало нормально, мгновенный чистый выход.

Хотя это не совсем то же самое, что и MIDI-буферы, есть сходство в том, что лучше всего держите процесс в целости, полностью очистите, затем выйдите. Со скромными кусками памяти это очень быстро. Я обнаружил, что многие мелкие буферы работали быстрее при работе и очистке, чем меньше крупных.

Исключения могут существовать, как сказал кто-то, избегая вывоза больших фрагментов памяти из файла подкачки на диске, но даже это может быть сведено к минимуму, сохраняя больше и меньше выделенных пространств.

0
ответ дан user 28 August 2018 в 06:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: