Рост ByteBuffer

Журнал Python, конечно! BTW они ищут участников...

40
задан rtruszk 14 December 2014 в 00:08
поделиться

5 ответов

Чтобы асинхронный ввод-вывод работал, у вас должна быть непрерывная память. В C вы можете попытаться перераспределить массив, но в Java вы должны выделить новую память. Вы можете записать в ByteArrayOutputStream , а затем преобразовать его в ByteBuffer , когда будете готовы его отправить. Обратной стороной является то, что вы копируете память, и один из ключей к эффективному вводу-выводу - уменьшение количества копий памяти.

36
ответ дан 27 November 2019 в 01:49
поделиться

Взгляните на Mina IOBuffer https://mina.apache.org/mina-project/userguide/ch8-iobuffer/ch8-iobuffer.html , который является drop in replace (он обертывает ByteBuffer)

Однако я предлагаю вам выделить больше, чем вам нужно, и не беспокоиться об этом слишком сильно. Если вы выделяете буфер (особенно прямой буфер), ОС предоставляет ему виртуальную память, но она использует физическую память только тогда, когда она фактически используется. Виртуальная память должна быть очень дешевой.

6
ответ дан 27 November 2019 в 01:49
поделиться

ByteBuffer не может работать таким образом, поскольку его концепция дизайна должна быть просто представлением определенного массива, на который вы также можете иметь прямую ссылку. Он не может попытаться заменить этот массив на более крупный массив без каких-либо странностей.

Вы хотите использовать DataOutput . Наиболее удобный способ - использовать (предварительную) библиотеку Guava:

ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.write(someBytes);
out.writeInt(someInt);
// ...
return out.toByteArray();

Но вы также можете создать DataOutputStream из ByteArrayOutputStream вручную и просто обработать ложные исключения IOExceptions, связав их в AssertionErrors.

10
ответ дан 27 November 2019 в 01:49
поделиться

Другой вариант - использовать прямую память с большим буфером. Это потребляет виртуальную память, но использует только столько физической памяти, сколько вы используете (на страницу, которая обычно составляет 4K)

Таким образом, если вы выделяете буфер размером 1 MB, он потребляет 1 MB виртуальной памяти, но ОС отдает приложению только физические страницы, которые оно фактически использует.

В результате вы видите, что ваше приложение использует много виртуальной памяти, но относительно небольшое количество резидентной памяти.

5
ответ дан 27 November 2019 в 01:49
поделиться

Возможно, стоит также взглянуть на Netty's DynamicChannelBuffer . Мне пригодились следующие вещи:

  • slice (int index, int length)
  • unsigned operations
  • разделенные индексы записи и чтения
4
ответ дан 27 November 2019 в 01:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: