NBIO: Nonblocking I/O for Java Release notes
Matt Welsh,
mdw@cs.berkeley.edu |
[Back to SEDA Release Documentation]
NBIO is a library which implements nonblocking I/O facilities for Java. Surprisingly, the standard JDK libraries (prior to JDK 1.4) do not provide nonblocking I/O. This means that in order to implement applications (such as web servers and other Internet services) which 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 which 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 native calls (through JNI) to create and manage nonblocking sockets, as well as to provide select()-like functionality (that is, to test for I/O readiness or completion across a large number of sockets). For event delivery, NBIO supports both the UNIX poll(2) system call and the /dev/poll event-delivery mechanism. (Note that select() itself is not used, mainly because on most UNIX systems select() does not perform well with a large number of sockets.) NBIO 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 simply work with, or at least be easy to port to, a large number of other UNIX systems.
We have also made a BETA release of NBIO for Windows 2000 systems. It is available from the SEDA SourceForge pages.
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.
Note that the Sandstorm system can use either NBIO or java.nio for nonblocking I/O.
If you are compiling the complete SEDA code tree (including NBIO, Sandstorm, etc.), simply follow the instructions in the Sandstorm release notes instead of those given here. If you only wish to compile NBIO, you need to configure the following environment variables:
For example, under Bourne-style UNIX shells, type:
CLASSPATH=$CLASSPATH:/path/to/seda/src:. export CLASSPATHUnder C-style shells:
setenv CLASSPATH "$CLASSPATH":/path/to/seda/src:.Replacing /path/to/seda with the directory where you unpacked the SEDA release.
Under Bourne-style shells,
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/seda/lib export LD_LIBRARY_PATHUnder C-style shells,
setenv LD_LIBRARY_PATH "$LD_LIBRARY_PATH":/path/to/seda/lib
To compile NBIO, simply cd to the seda/src/nbio directory and type make. If there are any problems with compilation, be absolutely sure that seda/src and "." are in fact on your CLASSPATH. This is the most common problem when building the code.
This package is called seda.nbio.
You can read the JavaDoc documentation for NBIO here. The public classes included in the package are:
In the test directory you will find a number of test programs which demonstrate the use of this library:
Note that NBIO is for use with NATIVE THREADS ONLY, not the "Green Threads" package supported by older JVMs. I believe that all JVMs from JDK 1.3 onwards only support native threads, so this is not a problem for most users. However, if you are using an older JVM with Green Threads, you need to be aware of this issue.
The problem is that a blocking call to SelectSet.select() actually blocks the OS thread making the call. If you are using Green Threads, this will block the entire JVM, because Green Threads uses a single OS thread to emulate many Java threads. This is fine for a single-threaded application, but in general you only want to block the Java 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. However, since Green Threads appears to be obsolete, I strongly recommend only using Native Threads with NBIO.
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:
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 32768to it.
echo 32768 > /proc/sys/fs/file-max echo 65536 > /proc/sys/fs/inode-max
ulimit -n 32768
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.
If anyone wishes to implement nonblocking file or disk I/O for NBIO,
please get in touch with the SEDA project developers.
This code is covered under the following Open Source license:
Copyright (c) 2002 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 / mdw@cs.berkeley.edu