Каковы подходы к оптимизации фазы оценки ГП без поколения?
Я работаю на сборщике мусора Boehm-Demers-Weiser, принадлежащем Unity, который не является генератором сборочных данных.
У меня есть большое дерево управляемых объектов в памяти (~100 000 объектов, ~200 МБ).
Эти объекты, по сути, являются кешем и никогда не выходят за рамки видимости, поэтому они никогда не будут очищены GC.
Однако, поскольку Бем не принадлежит к поколению, этот устаревший кеш никогда не переносится на более высокие поколения. Это приводит к тому, что фаза метки занимает очень много времени обработки, так как приходится обходить весь этот кэш в каждой коллекции, вызывая заметные скачки задержки.
Это "дизайн", как говорится в документации Unity:
Важно отметить, что сборка мусора в Unity, использующая алгоритм Boehm GC, не относится к поколению и не является компактной. "Non-Generation" означает, что GC должен проходить всю кучу при выполнении прохода сбора, и поэтому его производительность ухудшается по мере расширения кучи.
Мне хорошо известны подходы к сокращению повторяющегося выделения мусора, однако я не могу найти никакой информации о том, как оптимизировать большое, устаревшее базовое распределение в GC без генерации.
Более конкретно:
- Есть ли способ пометить корневой указатель (например, статическое поле) как полностью игнорируемый в GC?
- Существуют ли какие-либо шаблоны структуры данных, которые быстрее проходят в фазе разметки?
- И наоборот, существуют ли известные структуры данных, которые препятствуют фазовой скорости метки?
Эти вопросы являются лишь некоторыми из моих гипотез, чтобы решить эту проблему, но я открыт для всех предложений.
1 ответ
Можно приблизить поведение поколений, отделив запуск программы с инициализацией статических структур данных от работы в стационарном режиме. Все указатели в области памяти запуска могут быть проигнорированы, в то время как указатели из нее не должны существовать, так как ничего не выделено после того, как точка переключения (которая была бы под контролем GC) была еще выделена.
Можно даже один раз собрать GC в области запуска, прежде чем переключаться в новый регион. По сути, вы получите ограниченную форму неподвижного коллектора на основе регионов, где ссылки между регионами происходят только в одном направлении.