Простой ответ: среда исполнения Ruby имеет сборщик мусора. В зависимости от времени выполнения (GC поколения JRuby / JVM, GC поколения IronRuby / CLR, классический GC Ruby / mark-sweep) используются разные алгоритмы. Но основы довольно просты:
- По запросу о выделении ресурсов, если имеется «недостаточно свободной памяти» - сколько недостаточно, является одним из компонентов алгоритма GC - тогда GC начнет работу
- ГХ начинает с сканирования корней , которые являются глобальными переменными и местами в стеке (параметры и локальные переменные), чтобы определить, какие объекты еще живы; он отмечает каждый найденный объект
- Затем процесс GC просматривает ссылки (ссылки) внутри этих объектов и возвращается к тем объектам, которые еще не были отмечены
- Затем ГХ может начать перемещение / копирование всех отмеченных объектов, чтобы они были сжаты в памяти
- «Свободный указатель», из которого происходят новые выделения, сбрасывается до конца этого сжатого фрагмента памяти
- Если по-прежнему «недостаточно свободной памяти», то из операционной системы выделяется больше
- Все старые объекты, которые не были помечены в процессе сканирования, являются мусором и неявно удаляются в процессе копирования и сброса свободного указателя.
Частота сборов зависит от настройки ГХ, на которую может влиять операционная система, объем физической памяти, нехватка памяти операционной системы, управляемые пользователем изменения, изменения версии базовой платформы, динамически оптимизированные параметры и т. Д. Большая часть этого сводится к тому, чтобы решить, где находится планка в этом тесте «недостаточно свободной памяти», хотя с коллекционными поколениями все усложняется.