stringtranslate.com

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

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

Описание

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

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

Например

Ручное управление и корректность

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

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

Приобретение ресурсов — это инициализация

Ручное управление памятью имеет одно преимущество с точки зрения корректности, заключающееся в том, что оно позволяет автоматически управлять ресурсами с помощью парадигмы «получение ресурсов — это инициализация » (RAII).

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

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

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

Производительность

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

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

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

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

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

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

Ссылки

Смотрите также

Внешние ссылки