Compact String в java 9



По данным OpenJDK более 25% объектов в памяти занимают строки. По той же статистике 95% строк содержат только латинские символы и цифры, числовое значение которых умещается в 1 байт, а до 15% памяти заняты бесполезными нулями.



В java 8 символы хранятся в типе char и кодировке UTF-16. Занимают 8 или 16 бит. Экземпляр String содержит массив символов char[].



В java 9 вышло обновление Compact Strings. Символы теперь лежат в byte[] и хранятся в одной из двух кодировок. Кодировка записана в новом поле coder.



Это может быть:

1️⃣ ASCII кодировка Latin-1. Используется, если все символы строки умещаются в 1 байт. Т.е в тексте только латиница и цифры.

2️⃣ UTF-16 - если хотя бы один символ требует 16 бит.



Строки в разных кодировках по-разному лежат в памяти, и работать с ними нужно по-разному. Каждый метод в классе String начинается с проверки кодировки и разделяется на две ветки — для Latin-1 и UTF-16. Их код вынесен в отдельные классы StringLatin1 и StringUTF16.



Почему не UTF-8? Он же занимает ещё меньше места.



— UTF-8 действительно занимает меньше памяти, но работает он медленнее. Если символы в массиве одной длины, то адрес символа в памяти быстро ищется по индексу. Если элементы с переменной длиной - адрес вычисляется на основе предыдущих элементов, а это долго. Все методы класса String работали бы дольше.



Память сэкономили, кода стало в 3 раза больше. Стало ли быстрее?



— Любая дополнительная проверка снижает скорость работы, особенно при работе с маленькими строками. Поэтому на уровне JVM много оптимизаций по проверкам кодировки и сравнению строк, изменён механизм конкатенации и других операций. Именно за счёт внутренних оптимизаций компактные строки работают в среднем на 20% быстрее и создают на 30% меньше промежуточных объектов.



Самое главное - эти изменения никак не отразились на интерфейсе String. I/O классы, StringBuilder, StringBuffer тоже адаптированы без внешних изменений.



Нужно просто перейти на java 9 и приложение будет занимать на 5-15% меньше памяти.