Операционные системы выполняют ввод / вывод
операции над областями памяти. Эти
области памяти, насколько операционная
система обеспокоена, смежны
последовательности байтов. Это не удивительно
тогда только байтовые буферы
право на участие в I / O
операции. Также напомним, что
операционная система будет иметь прямой доступ
адресное пространство процесса, в
в этом случае процесс JVM, чтобы передать
данные. Это означает, что области памяти
которые являются объектами ввода / вывода, должны
быть смежными последовательностями байтов. В
JVM, массив байтов не может быть
хранится непрерывно в памяти, или
Сборщик мусора может переместить его в любой
время. Массивы являются объектами в Java, и
как данные хранятся внутри этого
объект может отличаться от одной JVM
реализация к другому.
По этой причине понятие
прямой буфер был введен. непосредственный
буферы предназначены для взаимодействия
с каналами и процедурами ввода / вывода.
Они делают все возможное, чтобы хранить
байтовые элементы в области памяти, что
канал может использовать для прямого или необработанного,
доступ с помощью нативного кода, чтобы сказать
операционная система для слива или заполнения
область памяти напрямую.
Прямые байтовые буферы обычно
лучший выбор для операций ввода-вывода. От
дизайн, они поддерживают наиболее
эффективный механизм ввода / вывода, доступный для
JVM. Непрямые байтовые буферы могут быть
передается на каналы, но при этом может
понести наказание за производительность. Это
обычно не возможно для непрямого
буфер, чтобы быть целью нативного
Операция ввода / вывода. Если вы передаете непрямой
Объект ByteBuffer для канала для
пишите, канал может неявно делать
следующее на каждый звонок:
- Создать временный прямой ByteBuffer
объект.
- Скопировать содержимое непрямого
буфер во временный буфер.
- Выполнение операции ввода-вывода низкого уровня
используя временный буфер.
- Объект временного буфера гаснет
области и в конечном итоге мусор
собраны.
Это может потенциально привести к буферу
копирование и отток объектов при каждом вводе / выводе,
которые именно такие вещи
мы хотели бы избежать Однако в зависимости
на реализации, вещи не могут
будь таким плохим. Время выполнения, скорее всего, будет
кэшировать и повторно использовать прямые буферы или
выполнять другие умные трюки, чтобы повысить
пропускная способность. Если вы просто создаете
буфер для одноразового использования,
разница не значительна. На
С другой стороны, если вы будете использовать
буфера неоднократно в
высокопроизводительный сценарий, вы
лучше выделять прямые буферы
и повторно их использовать.
Прямые буферы оптимальны для ввода / вывода,
но они могут быть дороже
создать непрямые байтовые буферы.
Память, используемая прямыми буферами,
распределяется путем вызова
родной, специфичный для операционной системы
код, минуя стандартную кучу JVM.
Настройка и снос прямой
буферы могут быть значительно больше
дороже, чем кучи резидентных буферов,
в зависимости от операционной системы хоста
и реализация JVM.
области памяти прямого буфера
не подлежат сборке мусора
потому что они вне стандарта
Куча JVM.
Компромисс производительности при использовании
прямые и непрямые буферы могут
широко варьируются в зависимости от JVM, операционной системы,
и дизайн кода. Распределяя память
вне кучи, вы можете подвергнуть
приложение к дополнительным силам
который JVM не знает. когда
принося дополнительные движущиеся части в
играть, убедитесь, что вы достигаете
желаемый эффект. Я рекомендую
старое программное обеспечение: сначала сделай это
работать, а затем сделать это быстро. Не беспокойся
слишком много об оптимизации заранее;
сосредоточиться в первую очередь на правильности.
Реализация JVM может быть в состояниивыполнять кэширование в буфере или другие оптимизации, которые обеспечат необходимую вам производительность, без лишних усилий с вашей стороны.