Проведя немного больше исследований в этом направлении, я даю другой ответ на свой вопрос (Переполнение стека говорит, что вполне приемлемо ответить на ваш собственный вопрос.)
Как Славомир говорит StringBuilder инициализируется с Latin1, несмотря ни на что.Предположим, вы пишете в основном на русском, китайском, хинди или греческом языках.Вы хотите создать строку, максимальный размер которой вы уже знаете, поэтому вы используете начальный аргумент емкости:
StringBuilder sb = new StringBuilder(4096);
sb.append("Здравствуйте!"); // Should easily fit in 4 kilobytes, right?
Тем не менее, приведенный выше вызов append
отбрасывает буфер 4 КБ, который вы ранее инициализировали, и выделяетновый буфер.Вы создали StringBuilder с начальной емкостью, чтобы избежать перераспределения буфера, но StringBuilder перераспределил его в любом случае.И он перераспределил его, даже если он уже был достаточно большим!
Обходной путь - запустить java с помощью опции JVM -XX:-CompactStrings
.
Если вы последовательно используете один изэти языки, тогда ваши строки будут использовать UTF-16 в любом случае, поэтому отключение сжатия строк при запуске уменьшит накладные расходы на проверку каждой строки, которую вы предоставляете, чтобы увидеть, может ли она быть сохранена с использованием кодировки Latin1.
См. также Доклад Хайнца Кабуца в jPrime Bulgaria, 29 мая 2019 года , где он заставляет StringBuilder исчерпать память из-за этой "функции".