DatagramChannel performance issue

Martin Thompson mjpt777 at gmail.com
Mon Aug 27 13:47:47 UTC 2018


Let me try and add some context to this.

If a service is being implemented then it will listen on a known
address and port. As requests arrive the the source will need to be
stored for sending back a response. These responses cannot use another
socket otherwise we have an issue with NAT traversal. As a service
processes requests from the client after the initial connect they only
need to create new socket address objects when a new source is
observed. This check can be a simple comparison of the source address
in bytes.

With the following signature we could implement better services.

    /**
     * Receive a datagram payload with associated source address and port.
     *
     * @param source  bytes representing source address and port.
     * @param payload bytes for the datagram.
     * @return true if a datagram has been received in non-blocking mode.
     */
    boolean receive(ByteBuffer source, ByteBuffer payload);

The source buffer could then be wrapped with a flyweight to extract
the source address and port to decide if a InetAddress and
InetSocketAddress need to be created, or extra methods applied to
InetAddress. For example:

    boolean matches(ByteBuffer source)

    InetAddress getByAddress(ByteBuffer source)

Port can be stored directly after the address in the source buffer.

This implementation could be utilised internally by the existing
receive implementation to make it more efficient and offered as a new
API so that UDP based services can be developed which are competitive
on performance with native implementations plus avoid unnecessary
allocation and JNI up calls.

Martin...



On Mon, 27 Aug 2018 at 13:08, Alan Bateman <Alan.Bateman at oracle.com> wrote:
>
> Moving this one to nio-dev.
>
> On 25/08/2018 17:42, Martin Thompson wrote:
> > We've been diagnosing a performance issue and isolated it to receiving
> > on a datagram socket
> > where we are seeing a significant step down in performance, and
> > increase in allocation, when
> > more than one source is sending.
> >
> > https://github.com/frohoff/jdk8u-jdk/blob/master/src/windows/native/sun/nio/ch/DatagramChannelImpl.c#L138
> >
> > When receiving from two or more sources we get InetAddress and
> > InetSocketAddress objects
> > allocated and they are set via multiple up calls from the JNI code into Java.
> >
> > A much more efficient implementation would be one that passes down two
> > ByteBuffers.
> > One to be filled in for the payload and one for the header. Allocation
> > on a per packet receive
> > is not a useful design for a network API.
> >
> > A read operation is not a valid alternative as we need the sender address.
> >
> > Regards,
> > Martin...
>


More information about the nio-dev mailing list