more about - System.arraycopy(...) equivalents for ByteBuffer/FileChannel

Jeff Hain jeffhain at
Sat Nov 3 10:06:44 PDT 2012

>>   That's also modulo the fact that, for BB to FC copies,
>> if the FileChannel is not readable, you can't use MBB
>> (no WRITE_ONLY mapping mode). A FileChannel.isReadable()
>> method would allow to use MBB for readable (and writable)
>> channels, without risk of an exception being thrown.
>It would although if code is running into then it suggests
>that it might not be using the API as intended.

  I mean, if dst.isReadable() is true, we try to map in READ_WRITE
mode (and it throws if dst is not writable: fine), and if
dst.isReadable() is false, we don't try to map (as there is no
WRITE_ONLY mode (which would require specific MBBs)), and just
use dst.write methods.
  That said, I don't know if writable-but-not-readable channels
can even exist (being new to IO stuffs).

>>   Intensive benches involving MBBs (namely FC to heap BB
>> copies) were hanging from time to time, up to nearly a second,
>> and then resumed at usual speed (slightly faster than temporary
>> direct ByteBuffer approaches).
>> ===>
>>   As a result, I completely disabled MBBs usage for my copies.
>Was this Windows 32-bit? We've seen a lot of issues with memory
>management on Windows where it takes time to write-out dirty pages
>and unmap the memory. I don't think we can do anything about this,
>assuming this is what you are running into. Windows 64-bit appears
>to be better although it can be a problem too when memory is over

Copying from FC to heap BB with MBBs, 64 times in a row
(same FC, same BB), from a same file (and -verbosegc to
make sure hangs are not GCs), using SSDs:
- on T2300/WinXP-32 (1Go RAM and not much left),
  - with a 40Mo file, each copy took about 60ms,
    with one hang of 200ms (260ms measured minus copy time).
- on 980X/Win7-64 (6Go RAM),
  - with a 40Mo file, each copy took about 17ms, with
    one hang of 60ms.
  - with a 200Mo file, each copy took about 80ms, with
    3 hangs of about half a second.
  - with a 400Mo file, each copy took about 170ms, with
    8 hangs of 250-600ms, twice next to each other.
  - with a 800Mo file, each copy took about 270ms, with
    11 hangs of 200-700ms.
For that last 800Mo bench, copy without MBB was steady 330ms.

>>   FileChannelImpl.transferFrom(...):
>>   This method can grow destination channel, but if the specified
>> position (in dst) is > dst.size(), it just returns 0. It looks
>> like a bug, as the spec says nothing about this surprising behavior.
>This is specified: " If the given position is greater than the file's
>current size then no bytes are transferred"

My bad. My surprise made me confident it was a problem, instead of
making me read the spec more carefully.

NB: In the code I linked (ByteCopyUtils), I had a bug in case of concurrent
src truncation or no space left on device, during a backward copy, where the
position was moved by the amount of bytes copied, i.e. as if the copy had been
done forward. It is now corrected and I throw whenever the copy stops earlier
than could be expected from initial src size and dst capacity.

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the nio-dev mailing list