Эта статья включает в себя список литературы , связанной литературы или внешних ссылок , но ее источники остаются неясными, поскольку в ней отсутствуют встроенные цитаты . ( Июль 2017 г. ) ( Узнайте, как и когда удалить этот шаблон сообщения ) |
- Мусор может также относиться к искаженным данным; См. Повреждение данных .
В компьютерной науке , мусор включает в себя данные , объекты или другие регионы памяти компьютерной системы (или других системных ресурсов), которые не будут использоваться в любых расчетах в будущем системы или программа , которая работает на нем. Поскольку каждая компьютерная система имеет ограниченный объем памяти и большая часть программного обеспечения производит мусор, часто необходимо освободить память, занятую мусором, и вернуть ее в кучу или пул памяти для повторного использования.
Классификация [ править ]
Мусор обычно подразделяется на два типа: синтаксический мусор , любой объект или данные, которые находятся в пространстве памяти программы, но недоступны из корневого набора программы ; и семантический мусор , любой объект или данные, к которым никогда не обращается запущенная программа при любой комбинации входных данных программы. Объекты и данные, которые не являются мусором, считаются живыми .
Небрежно заявил, синтаксический мусор данные , которые не могут быть достигнуты, и семантический мусор данные , которые не будут достигнуты. Точнее, синтаксический мусор - это данные, которые недоступны из-за ссылочного графа (к нему нет пути), который может быть определен многими алгоритмами, как обсуждалось в разделе «Трассировка сборки мусора» , и требует только анализа данных, а не кода. Семантический мусор - это данные, к которым не будет доступа, либо потому, что они недоступны (следовательно, также и синтаксический мусор), либо потому, что они доступны, но не будут доступны; последнее требует анализа кода и в целом является неразрешимой проблемой .
Синтаксический мусор - это (обычно строгое) подмножество семантического мусора, поскольку объект вполне может содержать ссылку на другой объект, даже не используя этот объект.
Пример [ править ]
В следующей простой реализации стека в Java каждый элемент, извлекаемый из стека, становится семантическим мусором, если на него нет внешних ссылок: [a]
открытый класс Stack { элементы частного объекта [] ; частный размер int ; общедоступный стек ( внутренняя емкость ) { элементы = новый объект [ емкость ] ; } public void push ( Object e ) { elements [ size ++] = e ; } public Object pop () { возвращаемые элементы [- размер ] ; } }
Это связано с тем, что по- elements[]
прежнему содержится ссылка на объект, но к объекту больше никогда не будет доступа через эту ссылку, поскольку он elements[]
является частным для класса, и pop
метод возвращает только ссылки на элементы, которые он еще не получил. (После уменьшения size
этот класс больше никогда не будет обращаться к этому элементу.) Однако знание этого требует анализа кода класса, который в целом неразрешим.
Если более поздний push
вызов повторно увеличивает стек до предыдущего размера, перезаписывая эту последнюю ссылку, тогда объект станет синтаксическим мусором, потому что к нему больше нельзя будет получить доступ, и он будет иметь право на сборку мусора.
Автоматический сбор мусора [ править ]
Пример автоматической сборки синтаксического мусора путем подсчета ссылок сборкой мусора может быть произведен с использованием интерпретатора командной строки Python :
>>> class Foo : ... "" "Это пустой тестовый класс." "" ... pass ... >>> bar = Foo () >>> bar <__ main__.Foo object at 0x54f30 >> >> дель бар
В этом сеансе создается объект, отображается его местоположение в памяти, а затем уничтожается единственная ссылка на объект - с этого момента невозможно использовать объект снова, поскольку на него нет ссылок. . Это становится очевидным, когда мы пытаемся получить доступ к исходной ссылке:
>>> bar Traceback (последний вызов последним): файл "<stdin>" , строка 1 , в ? NameError : имя 'bar' не определено
Поскольку теперь невозможно обратиться к объекту, объект стал бесполезным; это фигня. Поскольку Python использует сборку мусора, он автоматически освобождает память, которая использовалась для объекта, чтобы его можно было использовать снова:
>>> class Bar : ... "" "Это еще один класс тестирования." "" ... pass ... >>> baz = Bar () >>> baz <__ main__.Bar object at 0x54f30>
Bar экземпляр в настоящее время находится на месте памяти 0x54f30 ; в том же месте, где располагался наш предыдущий объект, экземпляр Foo . Поскольку экземпляр Foo был уничтожен, освобождая память, используемую для его хранения, интерпретатор создает объект Bar в том же месте памяти, что и раньше, эффективно используя доступные ресурсы.
Эффекты [ править ]
Мусор потребляет память кучи, и поэтому желательно ее собирать (чтобы свести к минимуму использование памяти, обеспечить более быстрое выделение памяти и предотвратить ошибки нехватки памяти за счет уменьшения фрагментации кучи и использования памяти).
Однако сбор мусора требует времени и, если он выполняется вручную, требует дополнительных затрат на кодирование. Кроме того, сбор мусора разрушает объекты и, таким образом, может вызывать вызовы финализаторов , выполняющих потенциально произвольный код в произвольной точке выполнения программы. Неправильная сборка мусора (освобождение памяти, которая не является мусором), в первую очередь из-за ошибок при ручной сборке мусора (а не ошибок в сборщиках мусора), приводит к нарушениям безопасности памяти (которые часто создают дыры в безопасности) из-за использования висящих указателей .
Синтаксический мусор можно собирать автоматически, и сборщики мусора были тщательно изучены и разработаны. Семантический мусор, как правило, не может быть автоматически собран, и, таким образом, вызывает утечки памяти даже в языках со сборщиком мусора. Обнаружение и устранение семантического мусора обычно выполняется с помощью специального инструмента отладки, называемого профилировщиком кучи , который позволяет видеть, какие объекты являются активными и как они достижимы, что позволяет удалить непреднамеренную ссылку.
Удаление мусора [ править ]
Проблема управления удалением мусора хорошо известна в компьютерных науках. Используются несколько подходов:
- Многие операционные системы освобождают память и ресурсы, используемые процессом или программой, когда они завершают свою работу. Простые или недолговечные программы, предназначенные для работы в таких средах, могут завершиться и позволить операционной системе выполнить любое необходимое восстановление.
- В системах или языках программирования с ручным управлением памятью программист должен явно организовать освобождение памяти, когда она больше не используется. C и C ++ - два хорошо известных языка, поддерживающих эту модель.
- Сборка мусора использует различные алгоритмы для автоматического анализа состояния программы, выявления и удаления мусора без вмешательства программиста. Многие современные языки программирования, такие как Java и Haskell, обеспечивают автоматическую сборку мусора. Однако это не недавняя разработка, так как она также использовалась в более старых языках, таких как LISP .
- В настоящее время проводятся исследования теоретико-типовых подходов (таких как определение региона ) к идентификации и удалению мусора из программы. Никакого общего теоретико-типового решения проблемы разработано не было.
Заметки [ править ]
- ^ Упрощено изпункта 6 « Эффективная Java» путем исключения изменения размера и явных исключений.
Внешние ссылки [ править ]
- Бенджамин Пирс (редактор), Advanced Topics in Types and Programming Languages , MIT Press (2005), ISBN 0-262-16228-8
- Ричард Джонс и Рафаэль Линс, Сборка мусора: алгоритмы автоматического управления динамической памятью , Wiley and Sons (1996), ISBN 0-471-94148-4