2

Мне интересно, как бы я закодировал класс утилизации ByteBuffer, который может получить мне ByteBuffer, который, по крайней мере, такой же большой, как указанная длина, и который может заблокировать ByteBuffer объекты, используемые для предотвращения их использования в то время как они используются моим кодом. Это предотвратит повторное построение DirectByteBuffers и такое снова и снова, вместо того, чтобы использовать существующие. Существует ли существующая библиотека Java, которая может сделать это очень эффективно? Я знаю, что Javolution может работать с переработкой объектов, но распространяется ли это на класс ByteBuffer в этом контексте с установленными требованиями?ByteBuffer recycling class

+2

Вы должны профиль, чтобы узнать, действительно ли это лучше - он, скорее всего, будет хуже, чем выделение нового объекта каждый раз, когда вам это нужно, и позволит сборщику мусора восстановить буферы. –

+1

Возможно, но я использую DirectByteBuffers, который может быть немного медленнее, чем распределение обычных ByteBuffers. Что бы ни случилось, так это то, что я много раз перехожу к методу, который выделяет новые DirectByteBuffers для взаимодействия с кодом на C++. –

ответ

4

Было бы более важно, чтобы быть более консервативным в вашей модели использования, в первую очередь. Например, есть много кода, который показывает выделение нового ByteBuffer на каждом OP_READ. Это безумие. Вам нужно всего два байтовых буфера для большинства соединений, один для ввода и один для вывода, и в зависимости от того, что вы делаете, вы можете уйти с точностью до одного. В чрезвычайно простых случаях, таких как эхо-сервер, вы можете уйти с одного BB для всего приложения.

Я бы посмотрел на это, а не на бумагу поверх трещин с еще одним слоем программного обеспечения.

3

Это просто совет, а не ответ. Если вы выполняете кэширование для DirectByteBuffer, тогда обязательно прочитайте о последствиях GC, потому что память, потребляемая DirectByteBuffer, не отслеживается сборщиком мусора.

Некоторые ссылки:

A thread - featuring Stack Overflow's tackline

A blog post on the same subject

And the followup

+0

Приветствия за это. Думая об этом, мне нужно быть более строгим в моей сборке мусора, ugh :) –

+0

Как следует из сообщения, может быть разумным выделить огромный прямой байтовый буфер и выделить его часть для использования, и поэтому проблема переходит к уменьшению фрагментации в созданной пользователем куче, для которой API еще важнее справиться с этим :) Я хочу избежать боли при написании распределителя кучи, если это возможно, lol –

+0

Звучит забавно, ну хотя бы в течение первых двух часов .. – daveb

1

Как правило, вы использовали комбинацию обертки ThreadLocal и SoftReference. Быстрее для упрощения синхронизации (устраните необходимость в нем, по существу); и последний, чтобы сделать буфер повторно утилизируемым, если памяти недостаточно, имея в виду другие комментарии по ГК вопросам с прямыми буферами). Это на самом деле довольно просто: проверьте, имеет ли SoftReference буфер с достаточно большим размером; если нет, выделите; если да, ясная ссылка. Когда вы закончите с этим, переустановите ссылку на точку в буфер.

Другой вопрос: нужен ли ByteBuffer по сравнению с обычным байтом []. Многие разработчики предполагают, что ByteBuffers лучше работают по производительности, но это предположение обычно не поддерживается фактическими данными (т. Е. Тестированием, чтобы увидеть, есть ли разница в производительности и в каком направлении). Причина, по которой байт [] часто может быть быстрее, заключается в том, что доступ к коду может быть проще, проще для HotSpot эффективно JIT.

+0

В конце концов, я думаю, что я использовал распределитель сляба Grizzly :) И для приложений Apache MINA я переписал класс IoBuffer, чтобы вместо этого использовать распределитель slab. –

+0

Прохладный, повторное использование существующих хорошо реализованных функций, как правило, является лучшим способом :) – StaxMan