Appendix A. NIO and the JNI

The Street finds its own uses for technology.

William Gibson

As discussed in Chapter 2, direct buffers provide a means by which a Java buffer object can encapsulate system, or “raw,” memory and use that memory as its backing store. In the Java realm, you do this by invoking ByteBuffer.allocateDirect( ), which allocates the system memory and wraps a Java object around it.

This approach — allocating system memory and constructing a Java object to encapsulate it — is new in JDK 1.4. In previous releases, it was not possible for the Java side to use memory allocated by native code. It’s possible for native code invoked through the Java Native Interface (JNI) to call back to the JVM and request that memory be allocated from the JVM heap, but not the other way around. Memory allocated in this way can be used by Java code, but there are severe restrictions on how the memory can be accessed by native code. This made it awkward for Java and native code to share memory spaces.

In JDK 1.2, things got a little better with the introduction of GetPrimitiveArrayCrit-ical( ) and ReleasePrimitiveArrayCritical( ). These new JNI functions gave native code better control of the memory area. For example, you could be confident that the garbage collector would leave it alone during a critical section. However, these methods also have serious restrictions, and the allocated memory still comes from the JVM heap.

Enhancements in JDK 1.4 brought three new JNI functions ...

Get Java NIO now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.