Ответ 1
Это единственная, самая важная диаграмма, которую вы должны запомнить и понять:
(источник: oracle.com)
Это происходит из Java SE 6 HotSpot [tm] Настройка сборки мусора виртуальной машины, единого места, где можно узнать все о внутренностях GC. Но чтобы ответить на ваши насущные вопросы:
Выделение новых объектов с помощью оператора new
(почти) всегда происходит в пространстве Eden. Но на самом деле Eden - это стек. Когда вы создаете новый объект, требующий N байтов, одиночный указатель перемещается на N байтов в этом стеке и так далее. Распределение происходит так быстро, без поиска свободного места, сжатия, чего угодно.
Конечно, этот стек не бесконечен, в какой-то момент мы достигнем его конца, запустив незначительный сборщик мусора. Также, скорее всего, несколько объектов уже являются мусором. Итак, что делает JVM в второстепенном GC:
график прохождения объектов, начиная с корней GC
скопировать все объекты, достижимые от корней GC, в одно из пространств выживших (без пробелов, мы знаем их все, и это один процесс)
стереть пространство eden (в основном, просто переместив этот указатель стека обратно в
0
)
В последующих второстепенных коллекциях есть дополнительные шаги:
- один из оставшихся в живых мест также рассматривается. Живые объекты как из Эдема, так и из одного пространства выживших копируются во второе пространство выживших. Это означает, что всегда есть только одно свободное место для выживших.
Так, как объекты заканчиваются в постоянном поколении? Сначала молодые объекты копируются в одно из мест выживших. Затем они копируются на другой и снова и снова. Как только данный объект перескочил назад и вперед слишком много раз (настраивается, по умолчанию 8), он переводится в постоянное пространство.
Major GC работает, когда оставшееся место заполнено.