str создает еще одну запись и ссылается на последнее значение
Зануда мод: не переменная что-то создает, а JVM помещает новую строку в пул, если использовать создание строки литералом, а не конструктором. А потом ссылку на выделенную область памяти помещает в str
В какой момент сборщик мусора решает очистить наш String Pool от лишних значений и почему он это делает не так быстро, что конкатенации строки считается дурным тоном?
До Java 6 String Pool жили в отдельной области памяти, которую GC не чистят (т.е. единожды объявленная строка жила до завершения программы, даже без ссылок). Начиная с 7-ки пулл перенесли в основную кучу, где его может почистить GC. Не не забываем, что и сам гарбадж коллектор не сферический конь, а имеет с десяток реализаций, в каждой из которых есть свои настройки - не копал эту тему, но подозреваю, что можно настроить "неприкосновенность" String Pool даже в общей куче (но зачем?)
Вторая часть вопроса бессмысленна. Забудь про строки. Пусть у тебя есть некий класс А. Твой вопрос эквивалентен следующему:
Почему считается дурным тоном создавать множественные объекты класса А и каждый из них присваивать в одну и ту же переменную? Это медленно и расточительно к ресурсам!
Upd. Тут подробнее:
https://topjava.ru/blog/rukovodstvo-po-string-pool...