Используют ли эти методы прямой доступ к памяти (DMA) в отличие от выдачи запросов прерывания (IRQ) для каждой передачи байта?
Спецификации соответствуют фактической реализации, и они не обязаны использовать какой-либо конкретный механизм. Это намекают в документации transferTo
(курсив):
Этот метод потенциально гораздо эффективнее, чем простой цикл, который считывает данные из этого канала и записывает в целевой канал. Многие операционные системы могут передавать байты непосредственно из кэша файловой системы на целевой канал, не копируя их.
«Потенциально», «много» ... так что никаких гарантий.
Имеет смысл предположить, что , вероятно, более эффективно использовать метод, если только незначительно, потому что вы разрешаете JVM сокращать собственный код (при использовании поддерживаемых типов каналов). «Простой цикл» они описывают произведения вроде как ниже:
ByteBuffer buf = ByteBuffer.allocateDirect(BUF_SIZE);
while (/* read more condition */) {
source.read(buf);
buf.flip();
target.write(buf);
buf.compact();
}
Обратите внимание, что, даже если этот фрагмент кода использует прямые буферы, вы все еще засовывая обратно в Java для управления буфером (чтение, флип, писать, компактный). Оптимизирующий компилятор может использовать, но он, вероятно, не будет.
Использование transferTo
/transferFrom
, однако, оставляет его в JVM, чтобы решить, как передать байты. Если платформа имеет встроенную поддержку такого рода передач, она может сделать это без создания промежуточных буферов. Если такой поддержки нет, the JVM can still implement a loop such as above.
Пример: предположим, что SocketChannel предлагается считывать данные непосредственно из FileChannel через transferFrom
. Недавно FileChannel был прочитан, а его содержимое находится в кеше операционной системы. Вместо того, чтобы читать и копировать байты в буфер, SocketChannel может указывать непосредственно в кэш-память ОС и начинать передачу оттуда. По крайней мере один раунд копирования устранен.
Теперь предположим, что сокет (A) фактически связан с каким-либо другим локальным процессом, например, используя какой-то канал, называемый SocketChannel B. Когда B начинает читать то, что он получил от A, он может действительно читать прямо из кэша файлов OS снова. Если тогда B просто использует transferTo
для другого канала ... вы получаете идею.
Оба. IRQ используется для передачи диска, который затем выполняется через DMA. Это не относится к NIO или Java: так работают операционные системы на протяжении десятилетий. Не настоящий вопрос. – EJP