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