Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JDK7 NIO.2 use Epoll etc. on Linux?

I am studying the architecture of networking IO APIs in different languages and had a query on how the Async IO APIs in Java are implemented underneath. The "old" stream IO APIs (pre 1.4) offered synchronous blocking read/write functionality. JDK 1.4 NIO APIs use epoll/select to test IO readiness (exposed to users via SelectableChannel and Selector, etc.). This is presumably the case on both Windows and *nix. This is the reactor pattern. Now, JDK7 introduced the NIO.2 API which, among other things, offers an asynchronous API (proactor pattern) , and uses internal (configurable) thread pools to do IO in the background, and callback to user code when complete. It presumably uses IOCP on Windows, but I was wondering: 1. what does it use on Linux, which is my primary platform of interest. Does it use epoll and friends, or does it use a threadpool to do blocking IO? 2. Is the actual IO in NIO.2 (irrespective of platform) done by user threads in the Java threadpool, or is it done by kernel threads, and the Java threadpool threads are responsible for just copying the bytebuffers and calling back to user code?

like image 941
Ankur Kanoria Avatar asked Nov 13 '15 12:11

Ankur Kanoria


1 Answers

If linux kernel >= 2.6 is detected, then the java.nio.channels.spi.SelectorProvider will use epoll.

Here is a piece of the DefaultSelectorProvider.java source (from Java 7):

public static SelectorProvider create() {
    String osname = AccessController.doPrivileged(
        new GetPropertyAction("os.name"));
    if ("SunOS".equals(osname)) {
        return new sun.nio.ch.DevPollSelectorProvider();
    }

    // use EPollSelectorProvider for Linux kernels >= 2.6
    if ("Linux".equals(osname)) {
        String osversion = AccessController.doPrivileged(
            new GetPropertyAction("os.version"));
        String[] vers = osversion.split("\\.", 0);
        if (vers.length >= 2) {
            try {
                int major = Integer.parseInt(vers[0]);
                int minor = Integer.parseInt(vers[1]);
                if (major > 2 || (major == 2 && minor >= 6)) {
                    return new sun.nio.ch.EPollSelectorProvider();
                }
            } catch (NumberFormatException x) {
                // format not recognized
            }
        }
    }

    return new sun.nio.ch.PollSelectorProvider();
}

Both NIO 2 and the "original" one (let's call it NIO 1) have to use the low-level event notification mechanisms or Linux AIO API (which is relatively new) because you never know what will be the kernel on machine your application runs. I would not be surprised to see that NIO 2 actually uses Linux AIO or maybe POSIX AIO (they are quite different).

like image 115
DejanLekic Avatar answered Oct 19 '22 22:10

DejanLekic