The new I/O (NIO) classes in java.nio
allow the creation and use of direct buffers. These buffers tremendously increase throughput for repeated I/O activities. However, their creation and reclamation is more expensive than the creation and reclamation of heap-based nondirect buffers because direct buffers are managed using OS-specific native code. This added management cost makes direct buffers a poor choice for single-use or infrequently used cases. Direct buffers are also outside the scope of Java's garbage collector, which ; consequently, injudicious use of direct buffers can cause memory leaks. Frequent Finally, frequent allocation of large direct buffers can cause an OutOfMemoryError
.
Noncompliant Code Example
This noncompliant code example uses both a short-lived local object, rarelyUsedBuffer
, and a long-lived, heavily used object, heavilyUsedBuffer
. Both are allocated in nonheap memory; neither is garbage collected.
Code Block | ||
---|---|---|
| ||
ByteBuffer rarelyUsedBuffer = ByteBuffer.allocateDirect(8192); // Use rarelyUsedBuffer once ByteBuffer heavilyUsedBuffer = ByteBuffer.allocateDirect(8192); // Use heavilyUsedBuffer many times |
Compliant Solution
This compliant solution uses an indirect buffer to allocate the short-lived, infrequently used object. The heavily used buffer appropriately continues to use a nonheap, non-garbage-collected direct buffer.
Code Block | ||
---|---|---|
| ||
ByteBuffer rarelyUsedBuffer = ByteBuffer.allocate(8192); // Use rarelyUsedBuffer once ByteBuffer heavilyUsedBuffer = ByteBuffer.allocateDirect(8192); // Use heavilyUsedBuffer many times |
Applicability
Direct buffers are beyond the scope of Java's garbage collector , which and can cause memory leaks if they are used injudiciously. In general, direct buffers should be allocated only when their use provides a significant gain in performance.
Bibliography
...