Какие из следующих строковых объектов будут готовы для сборки мусора? - PullRequest
0 голосов
/ 26 января 2019

Я немного сбит с толку, когда речь идет о пуле и куче констант Strings. Я хочу понять, когда строковый объект может быть использован для сборки мусора, поэтому принимая во внимание приведенный ниже код, который из следующих объектов Strings будет готовдля сборки мусора в java?

class Demo{
    public static void main(String args[]){
        String s1 = new String("hey");
        String s2 = s1;
        String s3 = "hey";
        String s4 = "hey";
        String s5 = new String("guys");
        String s6 = "guys";
        String s7 = "guYs";
        s1 = s1.concat("world");
        s7 = null;
        s8 = null;
    }
}

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Перво-наперво: у вас есть переменные, такие как 's1', и это указатели (на языке java, 'ссылки').Они похожи на карту сокровищ: они сами не являются сокровищами, они просто указывают направление, в котором находится сокровище.

В этом примере переменные - это карты сокровищ, а строки - сокровища.

В приведенном выше примере всего 7 сокровищ:

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

5-е сокровище - это строка, созданная с помощью new String("hey") - это передает ссылку на сокровище "hey" в конструктор строк.Все конструкторы ВСЕГДА создают новое сокровище, даже если это бессмысленное упражнение здесь (строки не могут быть изменены, так какой смысл, верно? Просто правило: вызов new означает новое сокровище, поэтому новое сокровище создано).Теперь карта сокровищ s1 указывает на уникальное сокровище, которое выглядит очень похоже на сокровище "hey".

s2 = s1 просто копирует карту сокровищ.Он ведет к тому же сокровищу, что и s1.

s3 становится картой сокровищ, которая указывает на существующее сокровище "hey".Это сокровище, отличное от того, на что указывают s1 и s1.

s4 становится той же картой сокровищ, что и s3.

s5 и s6 являются копией s1против s3 ситуация: 2 сокровища.

s7 совпадает с s3 / s4 / s6.

Тогда найден клад s1 (s1. - точкаis: возьмите эту карту сокровищ и найдите сокровище), и затем сокровище просят выполнить метод concat, передав ему ссылку на другое сокровище ("world").Реализация concat завершается созданием еще одного сокровища (он будет читать «heyworld») и возвращает карту сокровищ, указывающую на это новое сокровище.Затем вы выбрасываете карту сокровищ, указывающую на "hey" (но учтите, что это совсем не изменяет s2, которая все еще указывает на сокровище "hey"), и заменяете ее новой картой сокровищ, ведущей к "heyworld".

Вы, наконец, изменили s7 на пустую карту сокровищ, ведущую в никуда, а затем записали ошибку компилятора, поскольку s8 не существует.

На этом этапе кода давайте посмотрим, как7 сокровищ все еще можно найти:

"эй" - да, через s3 и s4.которые все еще указывают на это.И еще к делу.они всегда будут «найденными»;все, что вам нужно сделать, это запустить этот основной метод, который может произойти в любое время.Строки, буквально записанные в java-файлы, не исчезают.

"парни" - через s6.

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

Копия "парни": все еще через s5.

"heyworld" - да, s1 указывает на него.

Копия "эй": Нет, ненайти вообще.Это сокровище «недостижимо».

Таким образом, хей-копия теперь является коллекционной для мусора, и больше ничего нет.

7 сокровищ карты не подлежат сборуюридические лица;эти вещи существуют в стеке и сразу же исчезают без затрат в момент выхода из метода.

Работа локальных переменных в стеке несколько странна: на уровне класса они переводятся в неназванные слоты.Детали сложны, но достаточно сказать, что в каком-то месте в слоте может существовать, казалось бы, вещь без ссылки.Вы не можете быть уверены, пока метод действительно не выйдет, и в этот момент все локальные переменные (которые в данном примере являются картами сокровищ) немедленно исчезнут.

Кроме того, на практике сборка мусора непнуть, пока позже.Неотмеченные сокровища будут надолго застревать в песке.Самый быстрый способ справиться с ними - просто оставить их на песке.Пока пляж достаточно большой, нет смысла убирать пляж.Тема GC намного, намного сложнее, но как быстрый урок на ней: это произойдет не намного позже, и это хорошо.

0 голосов
/ 26 января 2019

Работает так.

Каждая строка, созданная с помощью оператора new, получит память из пространства кучи. Так что new String("a") == new String("a") это false.

Литералы без оператора new получают место в пуле строк. Так что "a" == "a" это true.

С вашим кодом я бы сказал, что s1, s2, s5, s7 готовы к GC. s3, s4, s6 объявлены как литералы, поэтому они будут храниться в пуле строк.

...