Я много раз сталкивался с утечками памяти. Обычно, когда я ухожу, malloc
как будто завтра не наступит, или болтаюсь, FILE *
как грязное белье. Обычно я предполагаю (читай: отчаянно надеюсь), что вся память очищается, по крайней мере, когда программа завершается. Существуют ли ситуации, когда утечка памяти не будет собрана при завершении или сбое программы?
Если ответ сильно различается от языка к языку, давайте сосредоточимся на C (++).
Обратите внимание на гиперболическое употребление фраз «как будто завтра не наступит» и «болтается ... как грязное белье». Небезопасность malloc
может навредить тем, кого любишь. Также будьте осторожны с грязным бельем.
c++
c
memory
memory-leaks
DilithiumMatrix
источник
источник
calloc
завтра не будет. Превосходно.Ответы:
Нет. Операционные системы освобождают все ресурсы, удерживаемые процессами при их завершении.
Это относится ко всем ресурсам, которые поддерживает операционная система: память, открытые файлы, сетевые соединения, оконные дескрипторы ...
Тем не менее, если программа работает во встроенной системе без операционной системы или с очень простой или ошибочной операционной системой, память может быть непригодной для использования до перезагрузки. Но если бы вы оказались в такой ситуации, вы бы, вероятно, не задавали бы этот вопрос.
Операционной системе может потребоваться много времени для освобождения определенных ресурсов. Например, порт TCP, который сетевой сервер использует для приема подключений, может занять несколько минут, чтобы освободиться, даже если он правильно закрыт программой. Сетевая программа может также содержать удаленные ресурсы, такие как объекты базы данных. Удаленная система должна освободить эти ресурсы при потере сетевого подключения, но это может занять даже больше времени, чем локальная операционная система.
источник
ipcrm
для ручной очистки есть linux.die.net/man/8/ipcrm .Стандарт C не указывает, что выделенная память
malloc
освобождается при завершении программы. Это делается операционной системой, а не все операционные системы (обычно они находятся во встроенном мире) освобождают память при завершении программы.источник
main
возврате вся память, выделенная имmalloc
, освобождается. Например, он говорит, что все открытые файлы закрываются до завершения программы. Для памяти, выделенной mymalloc
, она просто не указана. Теперь, конечно, мое предложение относительно ОС описывает то, что обычно делается, а не то, что предписывает Стандарт, поскольку в нем ничего не говорится об этом.std::atexit
также учитывает завершение программы черезstd::exit
, а также естьstd::abort
и (специфично для C ++)std::terminate
.atexit
было бы невозможно использовать. :-)Поскольку все ответы охватывают большинство аспектов вашего вопроса относительно современных ОС, но исторически есть один вопрос, о котором стоит упомянуть, если вы когда-либо программировали в мире DOS. Программы Terminant и Stay Resident (TSR) обычно возвращают управление системе, но находятся в памяти, которая может быть восстановлена программным / аппаратным прерыванием. Было нормально видеть такие сообщения, как «недостаточно памяти! Попробуйте выгрузить некоторые из ваших TSR» при работе с этими ОС.
Таким образом, технически программа завершается , но поскольку она все еще находится в памяти, любая утечка памяти не будет устранена, если вы не выгрузите программу.
Таким образом, вы можете рассматривать это как еще один случай, помимо того, что ОС не восстанавливают память либо потому, что она содержит ошибки, либо потому, что встроенная ОС предназначена для этого.
Помню еще один пример. Система управления информацией о клиентах (CICS), сервер транзакций, который работает в основном на мэйнфреймах IBM, является псевдоразговорным. При выполнении он обрабатывает данные, введенные пользователем, генерирует другой набор данных для пользователя, передает его в оконечный узел пользователя и завершает работу. При активации клавиши внимания он снова оживает, чтобы обработать другой набор данных. Из-за того, как она себя ведет, опять же технически, ОС не будет освобождать память от завершенных программ CICS, если вы не перезапустите сервер транзакций CICS.
источник
Как уже говорили другие, большинство операционных систем будут освобождать выделенную память при завершении процесса (и, возможно, другие ресурсы, такие как сетевые сокеты, дескрипторы файлов и т. Д.).
Сказав это, память может быть не единственным, о чем вам нужно беспокоиться при работе с new / delete (вместо raw malloc / free). Память, выделенная в new, может быть освобождена, но того, что может быть сделано в деструкторах объектов, не произойдет. Возможно, деструктор какого-то класса при уничтожении записывает в файл контрольное значение. Если процесс просто завершается, дескриптор файла может быть сброшен, а память освобождена, но это контрольное значение не будет записано.
Мораль истории, всегда убирай за собой. Не позволяйте вещам болтаться. Не полагайтесь на то, что ОС очистит после вас. Убирайся за собой.
источник
kill -9
появится какой-нибудь не оченьstd::exit
вызовет dtors,std::abort
не будет , могут быть неперехваченные исключения.Это скорее зависит от операционной системы, чем от языка. В конце концов, любая программа на любом языке получит память из операционной системы.
Я никогда не слышал об операционной системе, которая не перерабатывает память при выходе из программы / сбое. Поэтому, если ваша программа имеет верхнюю границу памяти, которую необходимо выделить, тогда вполне разумно просто выделить и никогда не освобождать.
источник
Если программа когда-либо превращается в динамический компонент («плагин»), который загружается в адресное пространство другой программы, это может вызвать проблемы даже в операционной системе с аккуратным управлением памятью. Нам даже не нужно думать о переносе кода на менее производительные системы.
С другой стороны, освобождение всей памяти может повлиять на производительность очистки программы.
Одна программа, над которой я работал, для определенного тестового примера требовалось 30 секунд или более для выхода программы, потому что она рекурсивно просматривала график всей динамической памяти и освобождала ее по частям.
Разумное решение - иметь там возможность и покрывать ее тестовыми примерами, но отключать ее в производственном коде, чтобы приложение быстро закрылось.
источник
Все операционные системы, заслуживающие этого титула, уберут беспорядок, который ваш процесс сделал после завершения. Но всегда есть непредвиденные события, что, если ему каким-то образом было отказано в доступе, и какой-то плохой программист не предвидел возможность, и поэтому он не пытается повторить попытку чуть позже? Всегда безопаснее просто очистить себя, ЕСЛИ утечки памяти критически важны - в противном случае не стоит усилий ИМО, если эти усилия дорогостоящие.
Изменить: вам нужно очистить утечки памяти, если они находятся на месте, где они будут накапливаться, например, в циклах. Утечки памяти, о которых я говорю, - это утечки, которые накапливаются в постоянное время на протяжении всей программы, и если у вас есть утечка любого другого типа, она, скорее всего, рано или поздно станет серьезной проблемой.
С технической точки зрения, если ваши утечки имеют "сложность" памяти O (1), они в большинстве случаев в порядке, O (logn) уже неприятны (а в некоторых случаях фатальны) и O (N) + недопустимы.
источник
Общая память в POSIX-совместимых системах сохраняется до вызова shm_unlink или до перезагрузки системы.
источник
Если у вас есть межпроцессное взаимодействие, это может привести к тому, что другие процессы никогда не завершат работу и не потребят ресурсы в зависимости от протокола.
Чтобы привести пример, я однажды экспериментировал с печатью на PDF-принтер на Java, когда я завершил JVM в середине задания печати, процесс буферизации PDF-файлов оставался активным, и мне пришлось убить его в диспетчере задач, прежде чем я смог повторите попытку печати.
источник