Я ищу способ десериализовать String
из byte[]
на Java с минимальным количеством мусора. Поскольку я создаю свой собственный сериализатор и десериализатор, у меня есть полная свобода реализации любого решения на стороне сервера (т. е. при сериализации данных) и на стороне клиента (т. е. при десериализации данных).
Мне удалось эффективно сериализовать String
без каких-либо накладных расходов на мусор, перебирая символы String's
(String.charAt(i)
) и преобразовывая каждый char
(16-битное значение) в 2x 8-битное значение. Существует хорошая дискуссия по этому поводу здесь а>. Альтернативой является использование Reflection для прямого доступа к String's
базовому char[]
, но это выходит за рамки проблемы.
Однако мне кажется невозможным десериализовать byte[]
без создания char[]
дважды, что кажется, ну, странным.
Процедура:
- Создать
char[]
- Повторите
byte[]
и заполнитеchar[]
- Создать строку с помощью конструктора
String(char[])
Из-за правил неизменяемости Java String
конструктор копирует char[], создавая двойные накладные расходы GC. Я всегда могу использовать механизмы, чтобы обойти это (небезопасное выделение String
+ отражение для установки экземпляра char[]
), но я просто хотел спросить, есть ли какие-либо последствия для этого, кроме того, что я нарушаю все соглашения о неизменности String's
.
Конечно, самым мудрым ответом на это было бы: «Да ладно, прекрати это делать и доверься GC, оригинальный char[]
будет чрезвычайно недолговечен, и G1 мгновенно избавится от него», что на самом деле имеет смысл, если char[]
меньше 1/2 размера области G1. Если он больше, char[] будет непосредственно выделен как огромный объект (т.е. автоматически распространяется за пределы области G1). Такие объекты чрезвычайно трудно эффективно собирать в G1. Вот почему каждое распределение имеет значение.
Есть идеи, как решить проблему?
Большое спасибо.
MutableString
и реализовать над ним множество традиционно тяжелых операций с мусором (например, fastpathString
split), а затем иметь методtoString(from, to)
, который создает экземпляр представления типаString
. Я могу сделать это. Но это потребует полного рефакторинга нашего приложения и использованияMutableString
s везде, где это возможно. Это хорошая идея, но я хотел сначала изучить альтернативы. - person SergioTCG   schedule 21.01.2015CharBuffer
иStringBuilder
, оба являются своего рода изменяемымString
(если вы не создали неизменяемое представление), есть методы для создания их облегченных подпоследовательностей, и все они реализуютCharSequence
,interface
, на котором пакет регулярных выражений, который фактически реализует операцияsplit
работает. И хотя выглядит так, содержимое символов постоянно копируется при преобразовании междуString
s,CharBuffer
s иStringBuilder
s при просмотре исходного кода, HotSpot предлагает для них специальные оптимизации… - person Holger   schedule 21.01.2015