NBIO: Nonblocking I/O for Java

Matt Welsh, Harvard University
Last updated 11 July 2002

Introduction

NBIO is a library that implements nonblocking I/O facilities for Java. Surprisingly, the standard JDK libraries (as of JDK 1.3) do not provide nonblocking I/O. This means that in order to implement applications (such as web servers and other Internet services) that support many concurrent I/O streams, a large number of threads must be used. However, the overhead of threading (in Java, as well as more generally) limits the performance of such an implementation.

What is needed is a nonblocking I/O library that allows a small number of threads to be used, along with a select() or poll() like mechanism to test for incoming I/O events on a large number of streams. This is what NBIO provides.

NBIO is implemented using a native code wrapper to nonblocking I/O, as well as the poll() system calls and /dev/poll event-delivery mechanism. The native code for this is found in the jni directory. This library is known to work on Linux 2.2 and 2.4 systems, Solaris 7 and 8, FreeBSD, and HP/UX. Because it uses standard UNIX system calls, it should either work or be easy to port to a large number of other UNIX systems. A beta release for Windows 2000 systems is available - see below. NBIO is open source software.

I am using NBIO as the basis for my thesis research on the staged event-driven architecture (or SEDA). While NBIO provides a low-level nonblocking I/O library for Java, SEDA is a complete architecture and runtime system for building well-conditioned Internet services. In particular, our Java-based Web server, using NBIO, outperforms both Apache and Flash, which are written in C. More information can be found at the SEDA web pages.

Some benchmark results comparing the use of NBIO with threaded server implementations can be found here. Newer results can be found in our SOSP'01 paper on SEDA.

NBIO is being used by a number of commercial products and open-source systems. One example is SwiftMQ, a free Java-based JMS Enterprise Messaging server, to provide superior scalability and performance for MQ-based applications. Read more here.

Note on JDK 1.4 java.nio package

The recently-announced JDK 1.4 beta includes the package java.nio which, among other things, provides nonblocking I/O primitives for Java. As it turns out I am on the expert group for the Sun Java Specification Request for this package (see this link for more details). More details on this new API can be found at this URL; as you can see, java.nio has been influenced somewhat by the NBIO APIs.

My plan is to continue developing and supporting NBIO until stable, released versions of JDK 1.4 are available on Linux both from Sun and IBM. At that point I will deprecate NBIO in favor of the new APIs, but NBIO will continue to be supported (although the development will be frozen). Migration from NBIO to java.nio should not be difficult. If you are in need of an efficient, working nonblocking I/O library for Java, my recommendation is to go ahead and use NBIO, and move over to java.nio once it is available.

Latest News

Code releases moved to SourceForge - July 11, 2002

I have decided to migrate hosting of the NBIO and SEDA projects to SourceForge.net. Access the SEDA/NBIO SourceForge pages here. Mailing lists have also moved to SourceForge - see below.

I have released NBIO v2.0 which is identical to v1.6 except that the package name has changed to seda.nbio.

Downloading NBIO

File downloads are hosted by SourceForge.net under the SEDA (Staged Event-Driven Architecture) project umbrella. Click here for the SEDA SourceForge Pages. You may download the latest NBIO release here:

Package Latest version Download

NBIO release v2.0, July 12, 2002 nbio-release-20020711.tar.gz

NBIO Win2k Beta February 14, 2002 More information

Debian Linux Packages: Maintained by Kenneth Pronovici () v1.4
v2.0
Debian GNU/Linux Stable (Woody)
Debian GNU/Linux Unstable (Sarge)

Anonymous CVS access is available for those users who want to maintain a "live" source tree. To check out the SEDA tree using anonymous CVS, use the following commands:

cvs -d:pserver:anonymous@cvs.seda.sourceforge.net:/cvsroot/seda login
         ( Just press enter when asked for a password )

cvs -z3 -d:pserver:anonymous@cvs.seda.sourceforge.net:/cvsroot/seda co seda
The NBIO code is found in seda/src/seda/nbio in this tree. See the file README in the tree for information on compilation and usage. All of the NBIO code is covered under an open-source license (see below).

Note that the CVS tree will be updated more frequently than the "official" releases. The official releases are meant to represent stable, tested versions of the software, while the CVS tree is the "live code" that is under constant development. Also, note that the CVS tree contains the complete SEDA project code, of which NBIO is just a part.

Mailing List

The mailing list for SEDA and NBIO are now hosted by SourceForge. The list is called seda-users and is a low-volume list for questions about SEDA and NBIO usage and development.

Click here to subscribe
Click here for archives

Package contents

This package is called seda.nbio.

You can read the JavaDoc documentation for NBIO here. The public classes included in the package are:

NonblockingInputStream
A subclass of java.io.InputStream which supports nonblocking semantics.

NonblockingOutputStream
A subclass of java.io.OutputStream which supports nonblocking semantics.

NonblockingSocket
A subclass of java.net.Socket which supports nonblocking semantics. Socket connection and read/write are nonblocking.

NonblockingServerSocket
A variant of java.net.ServerSocket which supports nonblocking semantics. Connection accept is nonblocking.

NonblockingDatagramSocket
A variant of java.net.DatagramSocket which supports nonblocking semantics. Socket read/write are nonblocking.

NonblockingMulticastSocket
A variant of java.net.MulticastSocket which supports nonblocking semantics. Socket read/write are nonblocking.

SelectSet
A class which implements select(), allowing you to poll for events across a number of nonblocking I/O streams. The interface is in fact very similar to the SVR4 poll() system call.

SelectItem
A class which represents a single nonblocking I/O stream to be used with SelectSet.

Test programs

In the test directory you will find a number of test programs which demonstrate the use of this library:

test/test
Blocking and nonblocking variants of a simple server and client application, used for demonstration purposes.

test/p2p-bench
The TCPBench program is a point-to-point TCP benchmark, like ttcp for Java. It can use either blocking or nonblocking sockets, and reports both round-trip latency and bandwidth for a given message size.

test/multi-bench
The MultiServer program is a benchmark which implements a simple TCP server which supports many connections. It is capable of using either nonblocking sockets (with a single thread) or blocking sockets (with many threads). It exchanges a series of packets which each client that connects to it. The benchmark reports the total bandwidth measured by the server. The MultiClient program is used as the client.

Using the library

To use this library you need to make the file seda/lib/libNBIO.so available on your LD_LIBRARY_PATH, for example by using the following command:

	export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/seda/lib

This library is for use with NATIVE THREADS ONLY. This is very important. The issue here is that calling SelectSet.select() actually blocks the thread making the call. If you are using Green Threads, this will block the entire JVM. This is fine for a single-threaded application, but in general you only want to block the thread making the call. Supporting this behavior under Green Threads is complicated and I don't think it's important; with the NBIO library you should be able to use native threads, since you will need much fewer of them than you would with blocking I/O.

Of course, you can use the other NBIO routines (nonblocking sockets, etc.) with Green Threads, since they do not block. SelectSet.select() is the only real problem.

If you are running on Linux 2.2.x systems you may wish to increase your file descriptor limit, which increases the number of simultaneous socket connections the system can have. This is important as one of the basic uses for NBIO is to write server applications which can support many simultaneous connections (many more connections than were possible using threads). This is relatively simple to do:

  1. Create the file /etc/initscript (if it does not already exist) and place the following commands into it:
    umask 022
    ulimit -c 2097151
    ulimit -Hn 32768
    PATH=/bin:/sbin:/usr/bin:/usr/sbin
    export PATH
    eval exec "$4"
    
    If /etc/initscript already exists, add the command
    ulimit -Hn 32768
    
    to it.

  2. Add the following commands to /etc/rc.d/rc.local (or some other startup script which is run at boot time):
    echo 32768 > /proc/sys/fs/file-max
    echo 65536 > /proc/sys/fs/inode-max
    

  3. Add the following command to your login scripts (e.g., .bashrc or .cshrc):
    ulimit -n 32768
    

  4. Reboot the system for the above changes to take effect.

In the future we would like to support nonblocking disk I/O, however, most UNIX-based operating systems do not in fact support nonblocking access to disk files; you must use a lower-level "raw disk" facility instead. Eventually We intend to extend this library to support Linux's raw disk I/O.

Copyright license

This code is covered under the following Open Source license:

Copyright (c) 2000 by Matt Welsh and The Regents of the University of California. All rights reserved.

Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without written agreement is hereby granted, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.

IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

If you have any questions, comments, or bug reports, don't hesitate to get in touch with me!


Matt Welsh, http://www.eecs.harvard.edu/~mdw

Project hosting by
SourceForge.net Logo