Дедупликация строки Java 8 против строки.интерн()
Я читаю о функции в Java 8 update 20 для дедупликации строк (подробнее), но я не уверен, что это в основном делает String.intern()
устарело.
Я знаю, что эта функция JVM нуждается в сборщике мусора G1, который может не быть вариантом для многих, но предполагая, что один использует G1GC,есть ли какая-либо разница/преимущество/недостаток автоматической дедупликации, выполняемой JVM vs вручную, чтобы intern
строки (один очевидный преимущество заключается в том, что не нужно загрязнять код вызовами intern()
)?
Это особенно интересно, учитывая, что Oracle может сделать G1GC GC по умолчанию в java 9
3 ответов
С этой функцией, если у вас есть 1000 различных строковых объектов, все с тем же содержимым "abc"
, JVM может сделать их одинаковыми char[]
внутренне. Тем не менее, у вас все еще есть 1000 различных String
объекты.
С intern()
, у вас будет только один
в качестве ссылок на комментарии см.:http://java-performance.info/string-intern-in-java-6-7-8/. Это очень проницательная ссылка, и я многому научился, однако я не уверен, что ее выводы обязательно "один размер подходит всем". Каждый аспект зависит от потребностей вашего собственного приложения-измерение реалистичных входных данных настоятельно рекомендуется!
основной фактор, вероятно, зависит от того, что вы контролируете:
вы имеете полный контроль над выбором ГК? В приложении GUI, например, все еще есть сильный случай для использования последовательного GC. (гораздо меньший общий объем памяти для процесса-подумайте о 400 МБ против ~1 ГБ для умеренно сложного приложения и гораздо более охотно освобождайте память, например, после переходного всплеска использования). Таким образом, вы можете выбрать это или дать своим пользователям возможность. (Если куча остается маленькой, паузы не должны быть большими).
у вас есть полный контроль над кодом? Опция G1GC отлично подходит для сторонних библиотек (и приложений!), который вы не можете редактировать.
второе соображение (согласно ответу @ ZhongYu )заключается в том, что String.intern
может де-дублирования String
сами объекты, тогда как G1GC обязательно может только де-дублировать их частные везде, который также работает последовательно, но затем...)
вам, вероятно, не нужна строка де-дублирование везде. Вероятно, есть только определенные области кода, которые:
- действительно влияет на долгосрочное использование кучи,и
- создать высокую долю повторяющихся строк
С помощью String.intern
выборочно, другие части кода (которые могут создавать временные или полу-временные строки) не платят цену.
и, наконец, быстрый плагин для утилиты Guava:Интернер, где:
обеспечивает эквивалентное поведение
String.intern()
для других неизменяемых типов
вы также можете использовать это для строк. Память, вероятно ,является (и должна быть) вашей главной проблемой производительности, поэтому это, вероятно, не применяется часто: однако, когда вам нужно выжать каждую каплю скорости из некоторой горячей точки, мой опыт заключается в том, что решения HashMap на основе слабых ссылок Java работают немного, но последовательно быстрее, чем реализация c++ JVM String.intern()
, даже после настройки параметров JVM. (И бонус: вам не нужно настраивать параметры JVM для масштабирования на другой вход.)
Я хочу ввести еще один фактор принятия решения о целевой аудитории:
- для системного интегратора, имеющего систему, состоящую из множества различных библиотек / фреймворков, с низкой способностью влиять на внутреннее развитие этих библиотек, StringDeDuplication может быть быстрым победителем, если проблема с памятью. Это повлияет на все строки в JVM, но G1 будет использовать только свободное время для этого. Вы даже можете настроить, когда дедупликация рассчитывается с помощью другого параметр(StringDeduplicationAgeThreshold)
- для разработчика, профилирующего свой собственный код, строка.интерн может быть интереснее. Вдумчивый обзор модели домена необходим, чтобы решить, следует ли вызывать стажера, и когда. Как правило, вы можете использовать intern, когда знаете, что строка будет содержать ограниченный набор значений, например, перечисленный набор (т. е. название страны, месяц, день недели...).