NIO optimization suggestions
Andrew Scully
andrewscully at gmail.com
Thu Jan 17 03:00:21 PST 2013
Hi,
After some recent “code surfing” of JDK 7, I have some observations
regarding some aspects of the NIO implementation, which may or may not be
correct or of use.
*java.nio.channels.Channels.java*
Channels.ReadableByteChannelImpl (a stream -> channel wrapper created by a
call to Channels.newChannel(InputStream) when the stream is not of type
FileInputStream) seems to have room for an optimisation, whereby the read
function may check the destination buffer’s hasArray value. If true, that
backing array may be directly transferred to, rather than going via an
intermediary byte array as it does in the default path.
Furthermore, the 8192 TRANSFER_SIZE used here to batch the transfer seems
to be arbitrary, given the circumstances. I appreciate it is a probably an
attempt to align with the 4096 typical HDD segment / socket buffer size,
but the wrapped stream may not have anything to do with such a resource. It
could be a ByteArrayInputStream for instance. I have had success using the
size of the destination buffer as a hint, instead, since memory has already
been safely allocated for the destination buffer. In many cases, the
transfer could be performed as a single bulk operation.
The “open” private boolean here appears to be unused.
*sun.nio.ch**.FileChannelImpl.java*
FileChannelImpl attempts to use sendFile (or the underlying OS’s
equivalent) for transferTo, but not for transferFrom. In cases where both
file descriptors refer to a FileChannel, surely zero-copy could be used on
many operating systems? I would have thought that, in some cases at least,
the source and destination arguments could be swapped and the existing JNI
call used, though I could be wrong.
>From the sendFile(3) man page:
…The in_fd argument should be a file descriptor to a regular file
opened for reading. See open(2). The out_fd argument should be a file
descriptor to a regular file opened for writing or…
Congrats on fixing http://bugs.sun.com/view_bug.do?bug_id=6431344, but I
suspect that the MAPPED_TRANSFER_SIZE being used in
transferToTrustedChannel is on the large side. Buffers of this size are
still a vulnerability that could be exploited by a sufficient volume of
concurrent requests. Much of the data I’ve seen suggests that the “sweet
spot” for this kind of transfer is around about the 256KB mark, though this
kind of data has a tendency to be totally unreliable!
Cheers, Andy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/nio-dev/attachments/20130117/e4eca7a6/attachment.html
More information about the nio-dev
mailing list