SCJP Вопрос к рисунку, когда объект получает мусор? - PullRequest
2 голосов
/ 01 апреля 2011

Я не могу понять вопросы SCJP даже после получения правильного ответа:

Из следующего кода (источник: http://scjptest.com), нам нужно определить, когда объект, на который ссылается myInt, будет иметь праводля сборки мусора:

01.public void doStuff() {  
02.    Integer arr[] = new Integer[5];  
03.    for (int i = 0; i < arr.length; i++) {  
04.        Integer myInt = new Integer(i);  
05.        arr[i] = myInt;  
06.    }  
07.    System.out.println("end");  
08.}

В ответе говорится, что он подходит для GC в строке 6. Но я думаю, что объект просто не подходит для GC до окончания строки 7. Поскольку объект ссылается как myIntтакже называется также arr [i], так что вы не думаете, так как после выхода myInt из области видимости arr [] все еще имеет ссылку на него до строки 8?

Ответы [ 5 ]

5 голосов
/ 01 апреля 2011

Обоснование ответа SCJP состоит в том, что в строке 6 в области действия arr отсутствуют остальные операторы, которые на него ссылаются.При нормальных обстоятельствах это делает массив и его элементы пригодными для сборки мусора.

(Спецификация языка Java (12.6.1) говорит следующее:

"Aдостижимый объект - это любой объект, к которому можно получить доступ в любом потенциальном продолжающемся вычислении из любого живого потока. Могут быть разработаны оптимизирующие преобразования программы, которые уменьшают число достижимых объектов до тех, которые наивно считаются достижимыми.компилятор или генератор кода может установить переменную или параметр, которые больше не будут использоваться для обнуления, чтобы в будущем хранилище для такого объекта могло быть потенциально восстановимо. "

AsВы можете видеть, что настоящее определение достижимости на самом деле не основано на определении объема.)


Есть еще один поворот в этом вопросе ...

Если бы они присвоили imyInt, при автобоксировании будет использоваться Integer.valueOf(i), и этот метод записал бы объект Integer в static caче.Этот кэш привел бы к тому, что объект оставался достижимым ...

Однако экземпляр Integer создается с использованием new, поэтому кэширование не происходит.И объект является недоступным в строке 6.

3 голосов
/ 01 апреля 2011

arr[i] = myInt создает копию ссылки на new Integer(i), а не ссылку на myInt; следовательно, myInt не обязательно должен существовать после этого назначения.

1 голос
/ 01 апреля 2011

Вопреки распространенному мнению, переменные объекта Java содержат ссылки на объекты, а не сам объект.Когда одна переменная объекта назначается другой, ссылка копируется вместо объекта.AFAIK GC для объекта, а не ссылки.Мы все знаем, что GC требует объект, когда не существует ссылки на него.

По моему мнению, объект, на который ссылается myInt, не будет доступен для сбора до тех пор, пока не вернется функция doStuff (строка 8).объект, на который ссылается myInt, сохраняется в arr, который находится в области видимости до возврата из функции.

0 голосов
/ 01 апреля 2011

С JLS §12.6.1 :

Достижимый объект - это любой объект, к которому можно получить доступ в любом потенциальном продолжающемся вычислении из любого живого потока.Могут быть разработаны оптимизирующие преобразования программы, которые уменьшают число достижимых объектов до меньшего, чем те, которые наивно считаются достижимыми.Например, компилятор или генератор кода может выбрать установку переменной или параметра, который больше не будет использоваться для обнуления, чтобы в будущем хранилище для такого объекта могло быть потенциально восстановимо.

Таким образом, согласно этому определению массив, на который ссылается arr, может считаться недоступным после строки 6, поэтому его элементы также недоступны.

0 голосов
/ 01 апреля 2011

arr и myInt в последний раз ссылаются на строку 5. Поскольку на них нет ссылки в строке 7, я могу понять, почему в строке 6 указан заявленный ответ.

...