FileChannel transferИз объяснения комментариев

Я прочитал комментарий к transferFrom FileChannel

 * <p> This method is potentially much more efficient than a simple loop
 * that reads from the source channel and writes to this channel.  Many
 * operating systems can transfer bytes directly from the source channel
 * into the filesystem cache without actually copying them.  </p>

Что это значит

Many operating systems can transfer bytes directly from the source channel
into the filesystem cache without actually copying them.

Если я читаю из канала, а затем записываю его в другой канал, разве он не передает байты в кеш?


person WoooHaaaa    schedule 26.06.2013    source источник


Ответы (1)


Да, если вы используете цикл и читаете из исходного канала в ByteBuffer, а затем записываете ByteBuffer в FileChannel, байты/данные будут в кеше файловой системы в конце записи. Они также будут скопированы в Java ByteBuffer, и это может быть копия из ядра, в память приложения (или «кучу C»), а затем в кучу JVM (в худшем случае).

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

Если вы увидите какое-либо реальное улучшение производительности, оно будет сильно зависеть от версии JVM, ОС и файловой системы. Я бы не ожидал, что он когда-либо будет работать хуже, чем цикл, закодированный в Java.

Роб.

person Rob Moore    schedule 26.06.2013
comment
Я пробовал, если я использую очень большой ByteBuffer, он будет быстрее, чем transferFrom, это нормально? - person WoooHaaaa; 26.06.2013
comment
И я не совсем понимаю ваш to application memory, разве JVM не работает напрямую с основной памятью? - person WoooHaaaa; 26.06.2013
comment
Это согласуется с тем, что я нашел в прошлом. Прошлое было пару лет назад. Для приложения, которое я создавал в то время, выделение больших буферов было нецелесообразным, поэтому я использовал буферы среднего размера (думаю, 8 КБ), и производительность была одинаковой на разных платформах. Только в одной комбинации JVM/OS/File System (не помню какой) было хуже, чем TransferFrom/To. Решающим фактором было то, что у меня была возможность предоставить информацию о ходе копирования, используя цикл чтения/записи. - person Rob Moore; 26.06.2013
comment
В Java действительно две кучи. 1) Куча Java, в которой выделяются объекты Java, и сборщик мусора безраздельно властвует. 2) Куча C, в которой размещены базовые структуры C и Direct ByteBuffers. Если вы читаете из файлового канала, в худшем случае может быть копия со страниц ядра, в буфер C, а затем в байт Java[]. - person Rob Moore; 26.06.2013
comment
Для меня это не имеет смысла, если JNI (код C) считывает его в память, нет необходимости снова читать его в Java Heap, я думаю, что JNI напрямую использует Java Heap. - person WoooHaaaa; 26.06.2013
comment
Он может, но не обязательно и не всегда может иметь байт [] кучи Java, доступный для использования для системного вызова read(). Существует также блокировка/защита, которая должна предотвратить сборщик мусора от перемещения объектов, если вы собираетесь передать указатель на память объекта Java в системный вызов ядра (который может заблокировать). - person Rob Moore; 26.06.2013