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()вручную по мере необходимости, чтобы предотвратить «утечку» дефицитных графических ресурсов. В зависимости от finalize()метода (как Java реализует финализаторы) освобождение графических ресурсов широко рассматривается среди Java-программистов как плохая практика программирования, и аналогичным образом на аналогичный __del__()метод в Python нельзя полагаться при освобождении ресурсов. Для ресурсов стека (ресурсов, приобретаемых и выпускаемых в рамках одного блока кода), это можно автоматизировать с помощью различных языковых конструкций, таких как Python with, C# usingили Java try-with-resources.

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

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

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

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

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

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

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

Рекомендации

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

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