1.3Kпросмотров
7 марта 2024 г.
questionScore: 1.4K
👀🗑Сборка мусора в Unity? Часть 6
После завершения сканирования и маркировки начинается сбор нод в куче. Логика запускается в методах GC_finish_collection -> GC_start_reclaim 1) Перед процессом этого этапа, очищаются ноды в памяти, в связанном списке OK_FREEList. Этот список нужен для того, чтобы добавить в него ноды в памяти, на которых нет ссылок.
2) Очищается OK_reclaim_list — это поле заголовка, которое специально установлено для освобождения небольших нод в памяти.
3) Вызов метода GC_apply_to_all_blocks. Он обходит все блоки HBLK управляемой памяти кучи. Метод GC_reclaim_block используется для предварительной обработки блока памяти, подлежащего освобождению. Для больших блоков памяти она освобождается напрямую, а для малых она временно добавляется в список OK_reclaim_list.
4) Метод GC_reclaim_all фактически перебирает небольшие объекты памяти. ⚡️Пункты 2, 3 — GC_reclaim_block
Большая память и маленькие блоки памяти обрабатываются по-разному. — Большая память является особенной, поскольку большой узел памяти обычно состоит из от 1 до N блоков памяти HBLK, в отличие от маленькой памяти, которая разделена на несколько небольших нод в HBLK. Далее в массиве заголовков GC ищет бит маркер факта ссылки. Если 0, значит большая нода не ссылающаяся. Значит можно добавить в список GC_hblkfreelist, очистив при этом данные в памяти. — Для маленьких нод, поскольку несколько узлов могут не ссылаться на блок памяти HBLK, применяется индивидуальная обработка, которая включает следующие три случая:
1) Если весь HBLK пуст, то есть HB_n_marks=0, это указывает на то, что в блоке памяти HBLK нет ссылающейся ноды. Отсюда, весь блок памяти передается непосредственно в GC_hblkfreelist для очистки данных.
2) Вызов метода GC_block_nearly_full, чтобы определить, ссылаются ли на большинство узлов в блоке памяти HBLK. Если нет, то добавляется блок памяти HBLK в список для освобождения ok_reclaim_list. Ok_reclaim_list — то же самое, что ok_freelist. Предоставляется 128 связанных списков. Блоки памяти HBLK добавляются в соответствующий список OK_reclaim_list в соответствии с размером внутренних равномерно разделенных узлов памяти.
3) Если блок почти полный и большинство узлов памяти в блоке памяти HBLK ссылающиеся — блок не добавляется в OK_reclaim_list. ⚡️Пункт 4 — GC_reclaim_all
Метод GC_reclaim_all обрабатывает все блоки памяти HBLK, которые только что были добавлены в ok_reclaim_list для небольших объектов и освобождает все узлы памяти. Выполняется метод GC_reclaim_generic и вызывается метод GC_reclaim_clear, чтобы освободить память. На этом всё. Сбор всех узлов памяти завершен.
В этой серии статей #boehm_gc не строго анализируются идеи реализации алгоритма BoehmGC в Unity по сборке мусора.
Многие детали упрощены, где-то разобраны поверхностно, поэтому все таки лучше разбирать этот материал не статьями, а последовательно в формате лекций. Далее будут публиковаться другие сборщики, работа с памятью в принципе. Но приоритет, конечно, на Unity.
Выводы, практика будут в других статьях. #thematic_post #gc #boehm_gc