Кратковременная сборка мусора

Опубликовано: 15 Февраля, 2023

Дизайн компилятора — сложная область. Он длинный, технический и часто требует компромиссов между различными функциями и производительностью. Но один конкретный набор вариантов дизайна может вызвать проблемы для сборщика мусора (GC) вашей программы. Это решение таково: вы используете сборщик мусора с короткой или длинной паузой? В этой статье мы обсудим, почему возникают проблемы с использованием коротких пауз в компиляторе, какие варианты доступны, если мы хотим использовать их, несмотря на эти проблемы, и как полностью избежать этих проблем.

Инкрементная сборка мусора:

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

Здесь вступает в действие техника сборки мусора «останови мир». Его можно использовать, когда вы имеете дело со многими потоками или процессами, которые совместно используют память, и все они должны быть остановлены на короткий период времени, чтобы сборщик мусора мог выполнить свою работу и определить, какие объекты в памяти больше не используются. ссылается на что-либо еще.

Техника остановки мира — это метод сборки мусора, при котором все потоки временно останавливаются, пока сборщик мусора выполняет свою задачу. Все объекты, на которые не ссылается другой объект в памяти, считаются мусором, и их память освобождается, чтобы ее можно было снова использовать другими приложениями или процессами.

Инкрементальный анализ достижимости:

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

Это используется, потому что позволяет нам собирать мусор раньше. Анализ достижимости также можно использовать для поиска циклов в структурах данных, что является одним из способов выявления потенциальных проблем с взаимоблокировкой или динамической блокировкой в параллельных программах.

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

Что нам нужно, так это способ отслеживать ссылки, указывающие на кучу, без необходимости хранить их где-то еще. Это позволяет нам очень быстро и эффективно выполнять анализ достижимости наших структур данных, поскольку все, что нам нужно сделать, это сравнить два указателя и посмотреть, указывают ли они на один и тот же объект или нет.

Основы частичного сбора:

Алгоритм частичного сбора — это алгоритм, который может собирать только часть мусора. Это означает, что он должен иметь возможность различать живые объекты и мертвые объекты, а также отслеживать, какие объекты являются живыми, чтобы они не собирались снова позже.

Наиболее распространенный способ реализации алгоритма частичного сбора — создание двух фаз: сначала идет старое поколение (O), которое собирает все живые объекты; затем приходит молодое поколение (Y), которое не собирает никаких предметов до тех пор, пока в них нет нужды. Это хорошо работает, когда в ваших структурах данных много указателей — это похоже на использование двух разных сканеров, один из которых может идентифицировать живые объекты, а другой не прекращает сканирование, пока его задача не будет выполнена!

Поколенческая сборка мусора:

Генерационный сбор мусора — это метод уменьшения количества объектов, которые необходимо проверить. Идея состоит в том, чтобы разделить объекты на поколения и собирать только одно поколение за раз.

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

Генерационный сбор мусора очень эффективен с точки зрения времени и пространства. Его можно реализовать с гораздо меньшими затратами, чем сборщики других типов, потому что ему не нужно отслеживать количество или типы живых объектов в любой момент времени, а также не нужно проверять все живые объекты, чтобы найти их. те, которые больше не нужны.

Алгоритм поезда:

Алгоритм обучения — это форма сборки мусора поколений, что означает, что он вычисляет новое поколение каждый раз, когда куча становится больше своего предыдущего размера, а затем копирует объекты из старых поколений в новые. Этот процесс можно повторять до тех пор, пока в любом поколении не останется живых объектов. Чтобы избежать ненужного копирования данных, этот алгоритм основан на предположении, что большинство объектов выживут во многих коллекциях без повторного перемещения.

Это означает, что копировать объекты из старого поколения в новое необходимо только в том случае, если в обоих поколениях есть живые объекты. Это предположение обычно верно, потому что в большинстве программ живых объектов гораздо больше, чем мертвых.

Этот алгоритм известен как «эфемерный сборщик», поскольку он перерабатывает объекты, которые больше не нужны программе. Он также известен как «сборщик поколений», потому что он разбивает память на разные поколения, каждое из которых имеет разный размер и предназначение. Самое молодое поколение состоит только из новых предметов; более старые поколения содержат объекты, которые были скопированы из более ранних.

Вывод

Сборка мусора — важная часть разработки компилятора, поскольку она влияет на производительность и продуктивность программиста. Как мы уже говорили, алгоритм обучения является одним из наиболее эффективных и масштабируемых алгоритмов GC (сборки мусора), но у него есть свои ограничения из-за его зависимости от сборки мусора с меткой и очисткой. В этой статье мы рассмотрели компромиссы, связанные с сборкой мусора с короткими паузами, рассмотрев как добавочный анализ достижимости, так и частичные сборки. С помощью этих и других методов вы можете создавать компиляторы, которые более эффективны, чем компиляторы, использующие только сборку мусора по меткам.