1

I've read the comment on FileChannel's transferFrom

 * <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>

What does it mean by

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

If I read from a Channel and then write it to another channel, doesn't it transfer bytes into cache ?

WoooHaaaa
  • 19,732
  • 32
  • 90
  • 138

1 Answers1

0

Yes, if you use a loop and read from the source channel into a ByteBuffer and then write the ByteBuffer to the FileChannel the bytes/data will be in the file system cache at the end of the write. They will have also been copied into the Java ByteBuffer and that might have been a copy from the kernel, to application memory (or the "C heap") and then into the JVM heap (in the worst case).

If the source channel is compatible then the OS may be able to avoid the copy into the JVM heap and maybe even out of the kernel entirely and instead do the copy directly from, say, the source file page into the destination file page.

If you will see any real improvement in performance will be highly JVM version, OS and file system dependent. I would not expect it to ever perform worse that a Java coded loop.

Rob.

Rob Moore
  • 3,343
  • 17
  • 18
  • I've tried, if I use a very large `ByteBuffer`, it will faster than `transferFrom`, is it normal? – WoooHaaaa Jun 26 '13 at 03:07
  • And I don't quite understand your `to application memory`, doesn't JVM operate main memory directly? – WoooHaaaa Jun 26 '13 at 03:13
  • That is consistent with what I have found in the past. The past being a couple of years ago. For the application I was building at the time allocating large buffers was not viable so I used moderate sized buffers (8K I think it was) and the performance was the same across platforms. Only in one JVM/OS/File System combination (cannot remember which) was it worse than transferFrom/To. The deciding factor was I got a chance to provide information on the progress of the copy using the read/write loop. – Rob Moore Jun 26 '13 at 03:18
  • There are really two heaps in Java. 1) The Java heap where Java objects are allocated and the garbage collector reigns supreme. 2) The C heap where underlying C structures are allocated and Direct ByteBuffers. If you read from a file channel in the worst case there may be a copy from kernel pages, into a C buffer and then into a Java byte[]. – Rob Moore Jun 26 '13 at 03:21
  • That's doesn't make sense to me, if JNI(C code) reads it into memory, there's no need to read it again to Java Heap, I think JNI use Java Heap directly. – WoooHaaaa Jun 26 '13 at 03:31
  • It can but it doesn't have to and may not always have a Java Heap byte[] available to use for the read() system call. There is also locking/safeing that has to happen to stop the Garbage collector from moving objects if you are going to pass a pointer to a Java object's memory into a kernel system call (which might block). – Rob Moore Jun 26 '13 at 03:49