Хранение неизменяемости Java String при изменении объекта String

Я понял, что если строка инициализируется литералом, ей выделяется место в пуле строк, и если она инициализируется новым ключевым словом, она создает объект строки. Но меня смущает случай, который написан ниже.

Мой вопрос: что, если строка создается с новым ключевым словом, а затем ее значение обновляется литералом?

E.g.

String s = new String("Value1");  -- Creates a new object in heap space

то что, если написать следующее утверждение, как показано ниже.

s = "value2";

Итак, мой вопрос:

1 Будет ли он создавать строковый литерал в пуле строк или обновлять значение этого объекта?

2 Если он создаст новый литерал в пуле строк, что произойдет с существующим в настоящее время объектом? Будет ли оно уничтожено или будет там, пока не вызовут сборщик мусора.

Это небольшая строка, если строка состоит, скажем, из тысяч символов, то меня просто беспокоит пространство, которое она занимает. Поэтому мой ключевой вопрос касается пространства.

Будет ли он сразу освобождать место из кучи после назначения литерала?

Кто-нибудь может объяснить, что и какое значение переходит от первого оператора ко второму, и что произойдет с областью памяти (кучей и пулом строк).


person Jitesh    schedule 14.09.2015    source источник
comment
Ключ к вашему вопросу - s не является объектом. Это ссылка на объект. Вы изменили ссылку, но не изменили здесь никаких объектов.   -  person Dmitry Zaytsev    schedule 14.09.2015
comment
Также обратите внимание, что объекты String неизменяемы. Следовательно, вы не можете обновить значение объекта String (напрямую. Отражение можно использовать для нарушения неизменности). В вашем конкретном случае строка 'value1', которая находится в куче, будет иметь право на сборщик мусора, как только s будет переназначено. Строковый литерал Value1 будет иметь право на сборщик мусора, когда загрузчик класса, загрузивший класс, в котором определен этот литерал, получит сборщик мусора.   -  person TheLostMind    schedule 14.09.2015
comment
@DmitryZaitsev Но, согласно ссылке, из которой я прочитал, если она инициализирована новым ключевым словом, она создаст объект в куче. Итак, есть пространство, занимаемое объектом. Итак, что произойдет с этим пространством, если ему будет назначен литерал (которого нет в куче).   -  person Jitesh    schedule 14.09.2015
comment
@TheLostMind утверждение (s=value2;) действительно (без ошибок компиляции или выполнения), оно позволяет обновить значение s. Так что же будет с пространством объектов?   -  person Jitesh    schedule 14.09.2015
comment
После изменения s = "value2"; объект, созданный с помощью new String("Value1");, будет иметь право на сборку мусора.   -  person Pshemo    schedule 14.09.2015
comment
Я имею в виду тот, который хранится в s (тот, который явно создан с помощью оператора new).   -  person Pshemo    schedule 14.09.2015
comment
@Jitesh - вы меняете то, на что указывает ссылка, а не значение. :)   -  person TheLostMind    schedule 14.09.2015
comment
examples.javacodegeeks.com/core-java/lang /string/ можно посмотреть по этой ссылке   -  person tarikfasun    schedule 14.09.2015


Ответы (2)


Изменение Strings

значение не обновляется при запуске

s = "value2";

В Java, за исключением примитивных типов, все остальные переменные являются ссылками на объекты. Это означает, что только s указывает на новое значение.

Неизменяемость гарантирует, что состояние объекта не может измениться после создания. Другими словами, в Java нет средств для изменения содержимого любого объекта String. Если вы, например, указываете s = s+"a";, вы создаете строку new, которая каким-то образом сохраняет новый текст.

Вывоз мусора

Этот ответ уже содержит подробный ответ. Ниже краткое резюме, если вы не хотите читать полный ответ, но в нем опущены некоторые детали.

По умолчанию объекты new String(...) не интернируются, поэтому применяются обычные правила сборки мусора. Это обычные предметы.

Постоянные строки в вашем коде, которые интернированы, обычно никогда не удаляются, поскольку вполне вероятно, что в конечном итоге вы вернетесь к ним.

Однако в ответе есть примечание о том, что иногда классы динамически (не) загружаются, и в этом случае литералы могут быть удалены из пула.


Чтобы ответить на дополнительные вопросы:

Будет ли он сразу освобождать место из кучи после назначения литерала?

Нет, это было бы не очень эффективно: сборщику мусора необходимо провести анализ того, какие объекты следует удалить. Возможно, вы поделились ссылками на свою старую строку с другими объектами, поэтому не гарантируется, что вы сможете повторно использовать объект. Кроме того, нет ничего плохого в хранении данных, которые больше не нужны, если вам не нужно запрашивать дополнительную память у операционной системы (сравните это со своим компьютером, если вы можете хранить все свои данные на жестком диске). , вам действительно не нужно беспокоиться о бесполезных файлах, с того момента, как вам придется покупать дополнительный диск, вы, вероятно, попытаетесь сначала удалить некоторые файлы). Анализ требует некоторых вычислительных усилий. Как правило, сборщик мусора запускается только тогда, когда ему (почти) не хватает памяти. Так что не стоит сильно беспокоиться о памяти.

Кто-нибудь может объяснить, что и какое значение переходит от первого оператора ко второму, и что произойдет с областью памяти (кучей и пулом строк).

Ваша первая строка:

String s = new String("Value1");

является ссылкой на кучу. Если вы вызовете команду, она выделит место в куче для строки.

Теперь, если вы позвоните:

s = "value2";

"value2" является элементом пула строк, он останется там до завершения вашей программы.

Поскольку у вас больше нет ссылки на вашу старую строку (value1). Этот объект является кандидатом на сбор. Если сборщик мусора позже пройдет мимо, он удалит объект из кучи и пометит место как свободное.

person Willem Van Onsem    schedule 14.09.2015

Если вам нужно изменить строку, вы всегда можете создать новую, содержащую изменения.

  • Java определяет одноранговый класс String, называемый StringBuffer, который позволяет изменять строки.
person Anil Kumar    schedule 14.09.2015
comment
Я думаю, что это должен быть комментарий, а не ответ. Я не буду dv, но я думаю, что некоторые будут :s. - person Willem Van Onsem; 14.09.2015