Будет ли строковый литерал неназначенным переменной вызывать утечку памяти в Java? - PullRequest
0 голосов
/ 06 марта 2020

Скажите, у меня есть функция, которая принимает строковый аргумент, такой как func("abc")

Будет ли интернирована "abc" (сохранена в пуле строк)? Если func("abc") будет вызван миллиард раз, java создаст миллиард копий строковых объектов "ab c" в пуле?

Ответы [ 3 ]

2 голосов
/ 06 марта 2020

Да, «ab c» будет храниться в пуле строк. Новая строка не создается, если вы явно не создадите ее с помощью оператора new.

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

2 голосов
/ 06 марта 2020

Из Java SE 13 документов , пожалуйста, прочитайте следующую выдержку:

Строковый литерал является ссылкой на экземпляр класса String (§4.3.1 , §4.3.3).

Более того, строковый литерал всегда ссылается на один и тот же экземпляр класса String . Это связано с тем, что строковые литералы - или, в более общем смысле, строки, являющиеся значениями константных выражений (§15.28) - «интернированы», чтобы совместно использовать уникальные экземпляры , используя метод String.intern (§12.5 ).

Строка "interning" в Java хранит объект String в пуле, так что несколько копий строкового литерала в вашем коде ссылаются на один и тот же объект String, а не на несколько одинаковых «Строковые объекты. Возможно, следующий пример прояснит это немного подробнее:

String hello = "Hello"; //A new String object with the value "Hello" is created in the String pool; the variable hello references that object in the pool
System.out.println(hello == "Hello"); //prints true

Так что в вашем случае, даже если вы продолжаете вызывать метод func миллиардов раз с одним и тем же литералом String, только 1 объект String с значение 'ab c' существует в пуле, и все литералы "ab c" ссылаются на один и тот же объект.

for (long i = Integer.MAX_VALUE; i <= Integer.MAX_VALUE; i++)
    func("abc"); //Only 1 String object is created

Однако, если вы явно создаете новые объекты String из литерала, вы можете в конечном итоге в памяти будет несколько объектов String с одним и тем же значением, пока объекты, не находящиеся в контексте, не будут удалены.

for (long i = Integer.MAX_VALUE; i <= Integer.MAX_VALUE; i++)
     func(new String("abc")); //multiple String objects with the same value are created and will continue to exist until garbage collected. 
2 голосов
/ 06 марта 2020

Нет. В пуле строк будет создана только одна копия, и все переменные, имеющие одинаковое строковое значение, будут направлены на эту копию.

Для большей ясности вы можете увидеть диаграмму ниже:

https://cdn.journaldev.com/wp-content/uploads/2012/11/String-Pool-Java1.png

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...