Ручное управление памятью

редактировать

В информатике, ручное управление памятью относится к использованию ручных инструкций программиста, чтобы выявить и освободить неиспользуемые объекты или мусор. Вплоть до середины 1990-х годов большинство языков программирования, используемых в промышленности, поддерживали ручное управление памятью, хотя сборка мусора существует с 1959 года, когда она была представлена ​​вместе с Lisp. Однако сегодня языки со сборкой мусора, такие как Java, становятся все более популярными, а языки Objective-C и Swift предоставляют аналогичные функции за счет автоматического подсчета ссылок.. Основные вручную управляемые языки все еще широко используются сегодня являются C и C ++ - см распределение C динамической памяти.

СОДЕРЖАНИЕ
  • 1 Описание
  • 2 Ручные методы управления памятью
  • 3 Ручное управление и правильность
  • 4 Приобретение ресурсов - это инициализация
  • 5 Производительность
  • 6 Ссылки
  • 7 Внешние ссылки
Описание

Все языки программирования используют ручные методы, чтобы определить, когда выделить новый объект из бесплатного хранилища. C использует malloc функцию; C ++ и Java используют new оператор; и многие другие языки (например, Python) выделяют все объекты из бесплатного хранилища. Определение того, когда должен быть создан объект ( создание объекта ), обычно тривиально и не вызывает проблем, хотя такие методы, как пулы объектов, означают, что объект может быть создан перед немедленным использованием. Настоящая проблема - это разрушение объекта - определение того, когда объект больше не нужен (то есть мусор), и организация возврата его базового хранилища в свободное хранилище для повторного использования. При ручном выделении памяти это также указывается вручную программистом; через функции, такие как free()C, или deleteоператор в C ++ - это контрастирует с автоматическим уничтожением объектов, содержащихся в автоматических переменных, в частности (нестатических) локальных переменных функций, которые уничтожаются в конце своей области видимости в C и C ++.

Методы ручного управления памятью

Например

Ручное управление и правильность
Основная статья: Безопасность памяти

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

  • Когда неиспользуемый объект никогда не возвращается в свободное хранилище, это называется утечкой памяти. В некоторых случаях утечки памяти могут быть допустимыми, например программа, которая «утекает» ограниченный объем памяти в течение своего времени жизни, или краткосрочная программа, которая полагается на операционную систему для освобождения своих ресурсов при завершении работы. Однако во многих случаях утечки памяти происходят в долго работающих программах, и в таких случаях происходит утечка неограниченного объема памяти. Когда это происходит, размер доступного бесплатного магазина со временем продолжает уменьшаться; когда он, наконец, исчерпан, программа вылетает.
  • Катастрофический отказ системы управления динамической памятью может произойти, если резервная память объекта будет удалена из-под нее более одного раза; объект явно уничтожается более одного раза; когда при использовании указателя для управления объектом, не выделенным в свободном хранилище, программист пытается освободить поддерживающую память указанного целевого объекта указателя; или когда, манипулируя объектом через указатель на другую произвольную область памяти, управляемую неизвестной внешней задачей, потоком или процессом, программист искажает состояние этого объекта, возможно, таким образом, чтобы писать за его пределы и повредить данные управления памятью. Результатом таких действий может быть повреждение кучи, преждевременное уничтожение другого (и вновь созданного) объекта, который занимает то же место в памяти, что и многократно удаленный объект, сбой программы из-за ошибки сегментации (нарушение защиты памяти ). и другие формы неопределенного поведения.
  • Указатели на удаленные объекты становятся дикими указателями, если используются после удаления; Попытка использовать такие указатели может привести к ошибкам, которые трудно диагностировать.

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

Приобретение ресурсов - это инициализация
Основная статья: Приобретение ресурсов - это инициализация

У ручного управления памятью есть одно преимущество правильности, которое заключается в том, что оно позволяет автоматическое управление ресурсами с помощью парадигмы Resource Acquisition Is Initialization (RAII).

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

Это также можно использовать с детерминированным подсчетом ссылок. В C ++ эта возможность используется для дальнейшего использования для автоматизации освобождения памяти в рамках ручной среды, использование shared_ptr шаблона в стандартной библиотеке языка для управления памятью является распространенной парадигмой. shared_ptrэто не подходит для всех моделей использования объекта, однако.

Этот подход неприменим в большинстве языков со сборкой мусора - в частности, для отслеживания сборщиков мусора или более продвинутого подсчета ссылок - из-за того, что завершение не является детерминированным, а иногда вообще не происходит. То есть трудно определить (или определить), когда или может ли быть вызван метод финализатора ; это обычно известно как проблема финализатора. Java и другие языки с GC часто используют ручное управление ограниченными системными ресурсами, помимо памяти, с помощью шаблона удаления : ожидается dispose(), что любой объект, который управляет ресурсами, реализует метод, который освобождает любые такие ресурсы и отмечает объект как неактивный. Ожидается, что программисты будут вызывать dispose()вручную по мере необходимости, чтобы предотвратить «утечку» скудных графических ресурсов. В зависимости от finalize()метода (как Java реализует финализаторы) освобождение графических ресурсов широко рассматривается как плохая практика программирования среди Java-программистов, и аналогичный __del__()метод в Python не может использоваться для освобождения ресурсов. Для ресурсов стека (ресурсы, полученные и выпущенные в одном блоке кода) это можно автоматизировать с помощью различных языковых конструкций, таких как Python with, C # usingили Java try-with-resources.

Представление

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

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

Ручное управление имеет ряд задокументированных недостатков производительности:

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

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

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

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

использованная литература
  • Бергер, ЭД; Zorn, BG; МакКинли, KS (ноябрь 2002 г.). «Пересмотр пользовательского распределения памяти». Материалы 17-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям. OOPSLA '02. С. 1–12. CiteSeerX   10.1.1.119.5298. DOI : 10.1145 / 582419.582421. ISBN   1-58113-471-1.
внешние ссылки
Последняя правка сделана 2024-01-01 06:33:40
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте