Выделение памяти кучи

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

или если он не освобожден, и я выполняю одну и ту же программу снова и снова, будет ли он выделять другой блок памяти каждый раз? Если это так, то как мне освободить это воспоминание?

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

6 ответов


короткий ответ: как только ваш процесс завершится, любая разумная операционная система освободит всю память, выделенную этим процессом. Поэтому нет, выделения памяти не будут накапливаться при повторном запуске процесса несколько раз.


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

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

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

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

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

один из способов защитить систему от утечек памяти-это гарантировать, что после завершения процесса вся память (и, возможно, другие ресурсы), которые она использовала, будут освобождены.


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

Если вы явно не free любой памяти malloc, он будет оставаться выделенным до завершения процесса.


даже если ваша ОС делает очистку на exit(). Syscall для выхода часто обернут


как мы говорим мозг операционной системы является ядро. Операционная система имеет несколько обязанностей.

Управление Памятью является функцией ядра.

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

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

это позволяет каждой программе вести себя так, как если бы она была единственной (отдельно из ядра) работает и, таким образом, предотвращает приложения от падения друг друга


Выделение Памяти

Танос

выделить блок памяти из кучу

. эквивалент .NET: не применимо. Чтобы вызвать стандартную функцию C, используйте вызов PInvoke.


Кучу

куча-это область памяти компьютера, что не удалось автоматически для вас и не так жестко управляется процессором. Это более свободно плавающая область памяти (и больше). Распределять память в куче, вы должны использовать malloc() или calloc(), которые встроенные функции C. После того, как вы выделили память в куче, вы ответственность за использование free() чтобы освободить эту память, как только вы она мне больше не нужна. Если вы этого не сделаете, ваша программа будет иметь то, что известно как утечка памяти. Что есть, память на куче будет все равно будет отложено (и не будет доступно для других процессов).


Утечка Памяти

Для Windows

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

предотвращение утечек памяти в приложениях Windows

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

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

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

. Вот несколько примеров общих шаблонов распределения:

  • памяти через HeapAlloc функция или ее среда выполнения C / C++ эквиваленты malloc или new

  • прямые выделения из операционной системы через VirtualAlloc функция.

  • ядро обрабатывает созданные через API Kernel32, такие как CreateFile, CreateEvent или CreateThread, удерживайте память ядра от имени применение

  • GDI и пользовательские дескрипторы, созданные через API User32 и Gdi32 (по умолчанию, каждый процесс имеет квоту в размере 10 000 ручек)

Для Linux

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


если я выделяю память динамически в моей программе с помощью malloc (), но я не освобождайте память во время выполнения программы, будет динамически выделенная память будет освобождена после завершения программы?

операционная система освободит память, выделенную через malloc, чтобы быть доступной для других систем.

Это намного сложнее, чем ваш вопрос звучит, так как физическая память, используемая процессом, может быть записана на диск (выгружается). Но с Windows, Unix (Linux, MAC OS X, iOS, android) система освободит ресурсы, которые она взяла на себя в этом процессе.

или если он не освобожден, и я выполняю одну и ту же программу снова и снова опять же, будет ли он выделять Различный блок памяти каждый раз? Если в этом случае, как я должен освободить эту память?

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

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

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

не освобождая память программы при ее выполнении будет "работать" на Windows и Unix, и, вероятно, любой другой разумной операционной система.

преимущества не освобождать память

операционная система хранит список больших блоков памяти, выделенных процессу, а также библиотека malloc хранит таблицы небольших блоков памяти, выделенных malloc.

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

недостатки не освобождая память

программы, такие как valgrind и application verifier, проверяют правильность программы, контролируя выделенную процессу память и сообщая об утечках.

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

несколько раз в моей карьере я преобразовывал процесс в общий объект/dll. Это были проблемные преобразования, из-за утечек, которые, как ожидалось, будут обработаны прекращением процесса ОС, начали выживать за пределами жизни "main".


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