Сколько объектов подходит для сборщика мусора, когда мы создаем массив массивов?

public class GarbageCollectionTest{

    public static void main(String...args){
        int [][]a = new int[4][3];//line 1
        a[0] = new int[2];// line 2
        a[2] = new int[3];// line 3
        a = new int[3][2];  //line 4
    }
}

Я немного смущен тем, сколько объектов имеют право на сборщик мусора после строки 3. Я искал решение по этому поводу, но ответы, которые я нашел, меня не удовлетворили.


person Gaurav Priyadarshi    schedule 23.07.2016    source источник
comment
Вы имели в виду после выполнения строки 4?   -  person SameeraB    schedule 23.07.2016
comment
Итак, вы переназначаете два объекта, поэтому я предполагаю, что у вас есть два объекта (два массива), доступных для сборки мусора.   -  person markspace    schedule 23.07.2016
comment
Что именно вы пытаетесь понять о сборке мусора? Вообще говоря, GC просто делает правильную вещь и очищает объекты, на которые вы больше не можете ссылаться.   -  person dimo414    schedule 23.07.2016


Ответы (2)


Хорошо, давайте пройдемся по строчке:

Вы создаете новый int 2D-массив a:

int [][]a = new int[4][3];//line 1

Вы заменяете два массива в a:

a[0] = new int[2];// line 2
a[2] = new int[3];// line 3

Вы переназначаете и создаете новый массив:

a = new int[3][2];  //line 4

После строки 3 будут выбраны два массива, которые вы заменили в строках 2 и 3.

После строки 4 сборщик мусора соберет каждый объект (массив), который был помещен в «старый» a, поэтому 4 объекта (int не объект, см. Ответ Константина здесь).

4 + 2 + ссылка на сам "старый" а = всего 7

Надеюсь, я правильно понял ;)

person Eric F.    schedule 23.07.2016

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

Двумерный массив примитивов, такой как int[][], состоит из одного массива объектов, содержащего ссылки на n int[] массивов (где n — размер внешнего массива — 4 дюйма). строка 1 вашего примера). Когда вы назначаете этот двумерный массив a, вы создаете ссылку из a на внешний массив и, в свою очередь, на внутренние массивы примитивов, поэтому сборщик мусора не удалит ни один из этих объектов.

Во второй строке вы создаете новый int[], а затем присваиваете его первому индексу внешнего массива. Это присваивание (а не создание массива) приводит к тому, что int[], который ранее был назначен индексу 0, становится пригодным для сборки мусора, поскольку больше нет никакого способа сослаться на него - это "мусор".

Третья строка такая же, вы создаете новый int[], затем назначаете его индексу, удаляя единственную ссылку на ранее указанный массив. Теперь он тоже подлежит сбору. Итак, после третьей строки есть два объекта int[], которые можно собрать.

Четвертая строка создает новый int[][], выполняя ту же работу, что и выше (один массив объектов, содержащий n массивов int[]), затем присваивает этот массив a, тем самым удаляя единственную ссылку на предыдущий двумерный массив. В этот момент сборщик мусора видит, что на старый массив ничего не ссылается, и очищает его. Как только это произойдет, не останется ссылок и на внутренние массивы, и сборщик мусора сможет их очистить.

После четвертой строки вы все еще можете ссылаться на этот новый массив через a и, в свою очередь, на содержащиеся в нем массивы. Массивы, которые вы создали ранее, больше недоступны и, следовательно, в конечном итоге будут очищены сборщиком мусора. Как только сборщик мусора сможет запуститься, все, что останется в памяти, — это массив, на который ссылается a, и внутренние массивы, на которые он, в свою очередь, ссылается.

person dimo414    schedule 23.07.2016