Мусор (информатика)
![]() | Эта статья включает список литературы , связанную литературу или внешние ссылки , но ее источники остаются неясными, поскольку в ней отсутствуют встроенные цитаты . ( Июль 2017 г. ) |
В информатике . мусор включает в себя данные , объекты или другие области памяти компьютерной системы (или другие системные ресурсы), которые не будут использоваться в каких-либо будущих вычислениях системой или программой, работающей на ней Поскольку каждая компьютерная система имеет ограниченный объем памяти, а большая часть программного обеспечения производит мусор, часто необходимо освободить память, занятую мусором, и вернуть ее в кучу или пул памяти для повторного использования.
Классификация
[ редактировать ]Мусор обычно подразделяется на два типа: синтаксический мусор , любой объект или данные, которые находятся в пространстве памяти программы, но недоступны из корневого набора программы ; и семантический мусор — любой объект или данные, к которым никогда не обращается работающая программа при любой комбинации входных данных программы. Объекты и данные, которые не являются мусором, называются живыми .
Проще говоря, синтаксический мусор — это данные, к которым невозможно получить доступ, а семантический мусор — это данные, к которым невозможно получить доступ. Точнее, синтаксический мусор — это данные, недоступные из-за графа ссылок (к нему нет пути), которые могут быть определены многими алгоритмами, как обсуждалось в трассировке сборки мусора , и требуют анализа только данных, а не кода. Семантический мусор — это данные, к которым невозможно получить доступ либо потому, что они недоступны (следовательно, это также синтаксический мусор), либо потому, что они доступны, но к ним невозможно получить доступ; последнее требует анализа кода и, как правило, является неразрешимой проблемой .
Синтаксический мусор — это (обычно строгое) подмножество семантического мусора, поскольку объект вполне может хранить ссылку на другой объект, даже не используя этот объект.
Пример
[ редактировать ]В следующей простой реализации стека на Java каждый элемент, извлекаемый из стека, становится семантическим мусором, если на него нет внешних ссылок: [а]
public class Stack {
private Object[] elements;
private int size;
public Stack(int capacity) {
elements = new Object[capacity];
}
public void push(Object e) {
elements[size++] = e;
}
public Object pop() {
return elements[--size];
}
}
Это потому, что elements[]
все еще содержит ссылку на объект, но никогда не будет осуществляться, поскольку доступ к объекту по этой ссылке больше elements[]
является частным для класса и pop
метод возвращает только ссылки на элементы, которые он еще не извлек. (После того, как он уменьшится size
, этот класс никогда больше не будет обращаться к этому элементу.) Однако знание этого требует анализа кода класса, что в общем случае неразрешимо.
Если позже push
call повторно увеличивает стек до предыдущего размера, перезаписывая эту последнюю ссылку, тогда объект станет синтаксическим мусором, поскольку к нему больше никогда нельзя будет получить доступ, и он будет иметь право на сбор мусора.
Автоматический сбор мусора
[ редактировать ]Пример автоматической сборки синтаксического мусора путем подсчета ссылок можно создать с помощью Python командной строки интерпретатора :
>>> class Foo:
... """This is an empty testing class."""
... pass
...
>>> bar = Foo()
>>> bar
<__main__.Foo object at 0x54f30>
>>> del bar
В этом сеансе создается объект, отображается его местоположение в памяти, а затем уничтожается единственная ссылка на объект — с этого момента невозможно когда-либо снова использовать объект, поскольку на него нет ссылок. . Это становится очевидным, когда мы пытаемся получить доступ к исходной ссылке:
>>> bar
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'bar' is not defined
Поскольку теперь невозможно ссылаться на объект, объект стал бесполезным; это мусор. Поскольку Python использует сбор мусора, он автоматически освобождает память, использованную для объекта, чтобы его можно было использовать снова:
>>> class Bar:
... """This is another testing class."""
... pass
...
>>> baz = Bar()
>>> baz
<__main__.Bar object at 0x54f30>
The Экземпляр Bar теперь находится в указанной ячейке памяти. 0x54f30 ; в том же месте, где находился наш предыдущий объект, Foo Экземпляр был расположен. Поскольку Экземпляр Foo был уничтожен, освободив память, использовавшуюся для его хранения, интерпретатор создает Разместите объект в том же месте памяти, что и раньше, эффективно используя доступные ресурсы.
Эффекты
[ редактировать ]Мусор потребляет память кучи, и поэтому его необходимо собирать (чтобы минимизировать использование памяти, обеспечить более быстрое выделение памяти и предотвратить ошибки нехватки памяти за счет уменьшения фрагментации кучи и использования памяти).
Однако сбор мусора требует времени и, если он выполняется вручную, требует дополнительных затрат на кодирование. Кроме того, сбор мусора уничтожает объекты и, таким образом, может вызвать вызовы финализаторов , выполняющих потенциально произвольный код в произвольной точке выполнения программы. Неправильная сборка мусора (освобождение памяти, которая не является мусором), в первую очередь из-за ошибок ручной сборки мусора (а не ошибок сборщиков мусора), приводит к нарушениям безопасности памяти (которые часто создают дыры в безопасности) из-за использования висячих указателей .
Синтаксический мусор можно собирать автоматически, а сборщики мусора тщательно изучены и разработаны. Семантический мусор в целом не может быть автоматически собран, что приводит к утечкам памяти даже в языках со сборкой мусора. Обнаружение и устранение семантического мусора обычно выполняется с помощью специализированного инструмента отладки, называемого профилировщиком кучи , который позволяет увидеть, какие объекты активны и как они доступны, что позволяет удалить непреднамеренную ссылку.
Устранение мусора
[ редактировать ]Проблема управления освобождением мусора хорошо известна в информатике. Применяется несколько подходов:
- Многие операционные системы освобождают память и ресурсы, используемые процессом или программой, после их завершения. Простые или недолговечные программы, предназначенные для работы в таких средах, могут завершить работу и позволить операционной системе выполнить необходимое восстановление.
- В системах или языках программирования с ручным управлением памятью программист должен явно организовать освобождение памяти, когда она больше не используется. C и C++ — два хорошо известных языка, поддерживающих эту модель.
- Сборка мусора использует различные алгоритмы для автоматического анализа состояния программы, выявления мусора и его освобождения без вмешательства программиста. Многие современные языки программирования, такие как Java и Haskell, обеспечивают автоматическую сборку мусора. Однако это не недавняя разработка, поскольку она также использовалась в старых языках, таких как LISP .
- Продолжаются исследования теоретико-типических подходов (таких как вывод областей ) для идентификации и удаления мусора из программы. Никакого общего теоретико-типического решения проблемы не разработано.
Примечания
[ редактировать ]- ^ Упрощено по сравнению с пунктом 6 «Эффективная Java» за счет отсутствия изменения размера и явных исключений.
Внешние ссылки
[ редактировать ]- Бенджамин Пирс (редактор), «Продвинутые темы по типам и языкам программирования» , MIT Press (2005), ISBN 0-262-16228-8
- Ричард Джонс и Рафаэль Линс, Сбор мусора: алгоритмы автоматического управления динамической памятью , Wiley and Sons (1996), ISBN 0-471-94148-4