Лекция
Это окончание невероятной информации про сборка мусора.
...
сборки мусора. При подсчете ссылок, в то время как выделение объектов обычно происходит быстро, уменьшение ссылки недетерминировано, поскольку ссылка может достигать нуля, вызывая рекурсию для уменьшения счетчиков ссылок других объектов, которые содержит этот объект.
Хотя сборка мусора обычно недетерминирована, ее можно использовать в системах жесткого реального времени . Сборщик мусора в реальном времени должен гарантировать, что даже в худшем случае он выделит определенное количество вычислительных ресурсов для потоков-мутаторов. Ограничения, накладываемые на сборщик мусора в реальном времени, обычно основаны либо на работе, либо на времени. Ограничение на основе времени будет выглядеть так: в каждом временном окне длительностью T потокам мутатора должно быть разрешено работать, по крайней мере, в течение времени Tm . Для анализа на основе работы MMU (минимальное использование мутатора) обычно используется в качестве ограничения в реальном времени для алгоритма сборки мусора.
Одним из первых реализаций жесткого реального времени сбора мусора для JVM была основана на метроном алгоритма , , чья коммерческая реализация доступна в рамках IBM WebSphere Real Time . [10] Другой алгоритм сбора мусора жесткого реального времени стаккато, доступны в IBM «s J9 JVM , которая также обеспечивает масштабируемость для больших многопроцессорных архитектур, принося различные преимущества по сравнению с метрономом и других алгоритмов , которые, наоборот, требуют специализированного оборудования . [11]
Сборка мусора как непременный атрибут среды исполнения программ используется в языках, основанных на декларативной парадигме, таких как LISP, ML, Пролог, Haskell. Ее необходимость в этом случае обусловлена самим характером этих языков, не содержащих средств ручного управления временем жизни объектов и не имеющих возможности естественной интеграции подобных средств. Основной сложной структурой данных в таких языках обычно является динамический односвязный список, состоящий из динамически выделяемых списочных ячеек. Списки постоянно создаются, копируются, дублируются, компонуются и разделяются, что делает практически нереальным ручное управление временем жизни каждой выделенной списочной ячейки.
В императивных языках сборка мусора является одним из вариантов, наряду с ручным и некоторыми альтернативными методиками[⇨] управления памятью. Здесь она рассматривается как средство упрощения программирования и предотвращения ошибок[⇨]. Одним из первых компилируемых императивных языков со сборкой мусора стал Oberon, продемонстрировавший применимость и достаточно высокую эффективность этого механизма для данного типа языков, но широкую известность и популярность данному подходу принес язык Java. Впоследствии подход Java был повторен в среде .NET и практически всех работающих в ней языках, начиная с C# и Visual Basic .NET. В то же время появилось множество интерпретируемых языков (JavaScript, Python, Ruby, Lua), куда сборка мусора включалась из соображений доступности языка для не-программистов и упрощения кодирования. Увеличение мощности аппаратуры, происходившее одновременно с совершенствованием самих сборщиков привело к тому, что дополнительные накладные расходы на сборку мусора перестали быть существенными. Большинство современных императивных языков со сборкой мусора вообще не имеют возможностей для явного ручного удаления объектов (например, оператора delete). В системах, использующих интерпретатор или компиляцию в байт-код, сборщик мусора является частью среды исполнения, в тех же языках, которые компилируются в объектный код процессора, он реализуется в виде обязательной системной библиотеки.
Имеется также небольшое количество языков (nim, Modula-3, D), поддерживающих как ручное, так и автоматическое управление памятью, для чего приложение использует две отдельные кучи.
Такие языки, как C, обычно могут подключаться к управлению памятью программы и выделять и освобождать ее в контексте программы. ECMAScript, с другой стороны, не имеет интерфейса для доступа к управлению памятью (да, это означает отсутствие соответствующего API). Что, в общем-то, означает, что все права на управление памятью в программе передаются V8.
Поскольку у нас нет доступа к бесконечному объему памяти, работа сборщика мусора заключается в том, что нужно перебрать все объекты, для которых выделена память, и определить, мертвы они или нет. Те, которые живы, должны остаться в памяти, те, которые мертвы, удаляются, а память возвращается обратно в кучу.
Переменная PHP хранится в контейнере, называемом "zval". Контейнер zval, помимо типа и значения переменной, также содержит два дополнительных элемента. Первый называется "is_ref" и представляет булево значение, указывающее, является переменная частью "набора ссылок" или нет. Благодаря этому элементу PHP знает как отличать обычные переменные от ссылок. Так как PHP содержит пользовательские ссылки, которые можно создать оператором &, контейнер zval также содержит внутренний механизм подсчета ссылок для оптимизации использования памяти. Эта вторая часть дополнительной информации, называемая "refcount" (счетчик ссылок), содержит количество имен переменных (также называемых символами), которые указывают на данный контейнер zval. Все имена переменных хранятся в таблице имен, отдельной для каждой области видимости переменных. Такая область видимости существует для главного скрипта, а также для каждой функции и метода.
Контейнер zval создается при создании новой переменной, которой присваивается константа
Хотя во всех областях видимости больше нет имени переменной, ссылающейся на данную структуру, она не может быть очищена, т.к. элемент массива "1" по-прежнему ссылается на этот массив. Т.к. теперь нет никакой возможности пользователю удалить эти данные, то мы получили утечку памяти. К счастью, PHP удалит эти данные при завершении запроса, но до этого момента данные будут занимать ценное место в памяти. Такая ситуация часто бывает, когда реализуются алгоритмы парсинга или другие, где есть дочерние элементы, ссылающиеся на родительские. Еще чаще такая ситуация случается с объектами, потому что они всегда неявно используются по ссылке.
Эта не проблема, если такое случается раз или два, но если существуют тысячи или даже миллионы таких утечек памяти, то они уже становятся проблемой. Особенно в долгоработающих скриптах, таких как демоны, где запрос не заканчивается никогда, или в больших наборах модульных тестов. Последний случай вызвал проблемы при запуске модульных тестов для компонента Template из библиотеки ez Components. В некоторых случаях может потребоваться свыше 2 Гб памяти, которая не всегда есть на тестовом сервере.
Обычно механизмы подсчета ссылок в памяти, например, используемый в PHP ранее, не решают проблему утечки памяти из-за циклических ссылок. Начиная с версии 5.3.0, в PHP реализован синхронный механизм ( сбор циклических ссылок ) из исследования " Concurrent Cycle Collection in Reference Counted Systems", в котором рассматривается этот вопрос.
В PHP есть возможность отключения этого механизма. Причиной этого, а также его ручного запуска, может стать то, что некоторые части вашего приложения могут быть требовательными ко времени. В этих случаях вы, возможно, не захотите постороннего вмешательства сборщика мусора.
Исследование, описанное в статье про сборка мусора, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое сборка мусора, утечка памяти, достижимость объекта, сбор циклических ссылок и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Языки и методы программирования. Теория трансляции
Часть 1 Отслеживание сборки мусора. Сборка мусора в программировании, утечка памяти
Часть 2 Требования к языку и системе - Отслеживание сборки мусора. Сборка
Часть 3 Сборка мусора в реальном времени - Отслеживание сборки мусора. Сборка
Комментарии
Оставить комментарий
Языки и методы программирования. Теория трансляции
Термины: Языки и методы программирования. Теория трансляции