Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску
Мусор может также относиться к искаженным данным; См. Повреждение данных .

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

Классификация [ править ]

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

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

Синтаксический мусор - это (обычно строгое) подмножество семантического мусора, поскольку объект вполне может содержать ссылку на другой объект, даже не используя этот объект.

Пример [ править ]

В следующей простой реализации стека в 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 .
  • В настоящее время проводятся исследования теоретико-типовых подходов (таких как определение региона ) к идентификации и удалению мусора из программы. Никакого общего теоретико-типового решения проблемы разработано не было.

Заметки [ править ]

  1. ^ Упрощено изпункта 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