Pull to refresh

Comments 26

IMPORTANT: Java 7 update 17 still has no changes in the subject of this article.
ВАЖНО: 17 апдейт 7 версии Java не содержит изменений, описанных в этой статье.
По-моему, смысл перевода получился диаметрально противоположным.
Переводчик погорячился конечно сильно
Спасибо за то, что не поленились проверить оригинал, а то моему возмущению не было предела касательно этого пункта.
Единственный способ этого избежать — вызвать конструктор new String(String), что заставит создать копию массива символов, то есть отсоединит вашу маленькую строку от большого «родителя».

Не единственный, еще можно intern() вызвать
Замечательное решение что бы убить приложение.
Потому что строки, полученные методом intern() попадают в PermGen
Я понял, что изменения вступили в силу только начиная с Java 1.7.0_06, а в Java 1.7.0 их нет.
Подскажите, кто разбирается в вопросе, то как реализован класс java.lang.String является частью какого-либо JSR и соответственно можно рассчитывать на единую реализацию, независимо от используемых JDK и JVM или это отдается на откуп вендорам и, например, для реализации от IBM, то о чем написано в статье может оказаться не актуальным?
Спецификация: docs.oracle.com/javase/7/docs/api/java/lang/String.html
Всё, что не является частью спецификации класса String — отдаётся на откуп вендорам. То есть они вольны использовать любую имплементацию: с оффсетами и без, с одними хэшкодами и с другими и т.п. Более того, они могут оптимизировать работу со строками под свои нужды. Не удивлюсь, если IBM тюнит в своей J9, которая идёт в составе WebSphere, работу со строками именно под типичные паттерны работы WebSphere.
Ради интереса посмотрел jdk 7 от IBM — там реализация String осталась прежней
Вероятно это потому, что их Java сделана на базе OpenJDK, а в релизе OpenJDK 7 летом 2011 года была именно прежняя имплементация. Думаю, если принципиальная схема работы IBM с OpenJDK за год кардинально не изменится, то этот фикс со строками попадёт к ним в восьмёрку.
ага, я буду следить и отпишусь сюда. А то различия в скорости String.substring в пределах одного вендора — как-то это меня парит.
Как я понял эти изменения касаются именно реализации от Oracle. Про реализацию от IBM без понятия…
> разделяет внутренний массив символов

по-русски было бы «использует совместно», а так смысл «разделяет» звучит как «split» и непонятно, какого фига оно пытается что-то разделить, а на самом деле имеется в виду «share». Это понятно из следующего текста, но… переводить тоже надо со смыслом, а не просто слова.
А что их вынудило поменять поведения Стринга? Откровенный даунгрейд, на первый взгляд.
да ладно))) Вы меряли производительность? Результаты в студию!

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

Есть мнение, что в некоторых случаях второй эффект может так загрузить GC, что копирование строк покажется детским лепетом.
Есть хорошая вероятность, что все эти ваши строки очень хорошо соберутся в стадии concurrent-mark и concurrent-sweep, при условии что мы их выкидываем, а если постоянно держим, то опять же, висят и висят, никого не трогают
Я не знаю, честно говоря, есть ли какая-то зависимлость работы CMS от размера собираемых объектов. Но полагаю, что с фрагментацией в старой Java проблемы сильнее при любом GC.
Дело может быть не только в производительности, но и в объёмах памяти. Если вы храните множество не очень длинных строк на протяжении работы всей программы, то раньше их можно было посадить на один массив, а теперь массивов много — для каждой строки добавляется оверхед на объект массива и выравнивание.
Другой юзкейс: читается какая-то длинная строка из потока (100500 символов), потом берётся какой-то её substring длиною 10, после чего сама строка нам не нужна, а массив чаров остаётся лежать огромный. Разница мложет составлять порядки

Короче говоря, зависит от паттерна использования. Видимо, описанный Вами паттерн не очень распространён.
Извините, это не юзкейс, а неумение пользоваться инструментом, который вам дали. Напишите new String(src.substring(1,10)) и всё.
так мы далеко зайти можем.
Дело в том, что пользы от данной оптимизации не так уж много, поэтому они решили от нее избавится.
Как известно, класс Random не очень дружелюбен с многопоточностью: он содержит поле private final AtomicLong seed. Atomics работают неплохо при средней нагрузке, но плохо при большой нагрузке.
Во-первых, с чего это Atomic* — это «не очень дружелюбен с многопоточностью».
Во-вторых, атомики работают плохо при рейс кондишне, и, я не знаю что нужно делать, что бы созданием таких объектов как мапы забить cas до состояния, когда на нем просядет производительность.

Sign up to leave a comment.

Articles