Вам нужно немного помочь с базовыми предположениями о том, как работает GC.
Предположим, вы используете HotSpot с G1, поскольку есть несколько других альтернатив, которые работают по-разному (например, C4 вЗинг из Азула, на которого я работаю).
Куча разделена на две области, называемые молодым и старым поколением. Когда объекты впервые выделяются, пространство предоставляется из пространства Эдема, которое является частью молодого поколения (иногда крупные объекты выделяются непосредственно в старом поколении. Но давайте будем простыми, как в вашем примере). Распределение в пространстве Eden использует простой метод натяжения указателя, что приводит к очень быстрому распределению.
Когда текущий указатель выделения достигает конца доступного диапазона памяти, происходит незначительный сборщик мусора. Это копирует объекты в пространство для выживших, между пространствами для выживших и продвигает долгоживущий объект для старого поколения. Затем указатель выделения сбрасывается в начало пространства Eden, что фактически бесплатно собирает весь мусор.
Старый ген. является отдельной логической областью памяти и использует различные алгоритмы для освобождения места и устранения фрагментации. Это основная коллекция.
Когда эти коллекции происходят, определяется не тем, где расположен объект, а тем, когда виртуальная машина решает, что коллекция необходима. Это будет определяться тем, когда пространство Eden исчерпано или когда в старом поколении появится свободное место. падает ниже определенного порога.
В вашем первом примере нет никакой гарантии, что объект 'a' будет собран во время второстепенного сбора мусора. Если doSomething () занимает много времени, и есть другие потоки, выделяющие много объектов, может произойти несколько второстепенных GC, и «a» может в конечном итоге перейти в старое поколение. (и собраны как часть основного GC).
В случае вашего второго примера, если doSomething () быстро вернулся и нигде не записал ссылку на 'b', то и 'a', и 'b' можно было бы собрать как часть вспомогательного GC.