Ответ
Сборщик мусора (GC) в .NET использует три поколения для организации управляемой кучи (Managed Heap): Gen 0, Gen 1 и Gen 2. Эта модель, называемая поколенческой (generational), основана на эмпирическом наблюдении, что большинство объектов живут недолго (гипотеза слабого поколения).
- Поколение 0 (Gen 0): Содержит недавно созданные объекты. Это самое молодое поколение, и сборка мусора здесь происходит наиболее часто. Размер Gen 0 самый маленький.
- Поколение 1 (Gen 1): Служит буфером между Gen 0 и Gen 2. Сюда перемещаются объекты, пережившие сборку мусора в Gen 0. Сборка в Gen 1 происходит реже, чем в Gen 0.
- Поколение 2 (Gen 2): Содержит долгоживущие объекты, пережившие несколько сборок мусора. Это самое старшее и обычно самое большое поколение. Полная сборка мусора (Gen 2) — наиболее затратная операция.
Отдельно существует Куча больших объектов (Large Object Heap — LOH), куда помещаются объекты размером ≥ 85 000 байт (≈85 КБ). LOH собирается только во время сборки Gen 2 и не подвергается уплотнению (compaction) по умолчанию, что может приводить к фрагментации.
// Пример, демонстрирующий поколение объекта
var obj = new object();
Console.WriteLine(GC.GetGeneration(obj)); // Скорее всего выведет 0
// Принудительная сборка мусора только для Gen 0 и Gen 1
GC.Collect(1);
// После выживания в сборке, поколение объекта увеличится
Console.WriteLine(GC.GetGeneration(obj)); // Может вывести 1 или 2 Ответ 18+ 🔞
Слушай, вот этот ваш сборщик мусора в .NET — он, блядь, реально умный, не то что я вчера на кухне. Устроен он по принципу трёх поколений, как в какой-нибудь ебучей саге: есть младшенькие, есть середнячки, есть старички-деды. И называется это всё — поколенческая модель, generational, если по-умному.
А придумали её на основе простой, блядь, идеи, которая в жизни всегда работает: большинство объектов — как мальки, живут недолго, создались-поработали-сдохли. Гипотеза слабого поколения, называется. Ну, как студенты после сессии.
Так вот, поколения:
- Поколение 0 (Gen 0): Это, сука, ясли. Только что созданные объекты, сопляки. Сборка мусора тут проходит чаще всего, потому что они дохнут пачками. Размер у этих яслей — самый маленький, чтоб быстро проветривать.
- Поколение 1 (Gen 1): Это уже типа буфер, переходный возраст. Сюда попадают те, кто выжил после чистки в Gen 0. Не герои ещё, но уже и не трупы. Убираются здесь пореже, но метко.
- Поколение 2 (Gen 2): А вот это, блядь, элита, долгожители. Объекты, которые пережили кучу сборок. Они тут обосновались, обросли связями. Это поколение — самое большое и самое дорогое по части уборки. Полная сборка мусора (когда чистится Gen 2) — это пиздец на несколько секунд, все потоки замирают.
А ещё есть, внимание, отдельная помойка для толстых — Large Object Heap (LOH). Туда скидывают всех, кто больше 85 000 байт. Представь себе диван, который на лестничную клетку не влезает. Так вот, эту кучу чистят только вместе с уборкой у дедов (в Gen 2), и диваны там обычно не переставляют (уплотнения по умолчанию нет), поэтому она может превратиться в шкаф-купе, забитый хернёй, — фрагментация, короче.
// Смотри, как поколение объекта меняется
var obj = new object(); // Родился, падаван
Console.WriteLine(GC.GetGeneration(obj)); // Почти наверняка покажет 0
// Щас устроим небольшую чистку, только для молодёжи и середнячков
GC.Collect(1);
// Если наш объект выжил, он стал круче
Console.WriteLine(GC.GetGeneration(obj)); // Может уже 1 или даже 2, смотря как повезло
Вот и вся магия. Создаётся объект — он в яслях. Выживает после уборки — переезжает в старшую группу. Не помер за долгие годы — становится патриархом. А если разъелся до неприличных размеров — его отправляют в спец-блок для толстых, где уборка раз в полгода и всё в хлам. Красота, ёпта.