Summary
Add support for Direct I/O by means of a JDK-specific OpenOption
specified to java.nio.channels.FileChannel
when creating or opening a file.
Problem
Some sophisticated applications maintain their own file caches. In such situations it can be desirable and can improve performance to have file reads and writes transfer data directly between user space buffers and the file system thereby bypassing the operating system read and write caches altogether. This can in appropriate circumstances improve performance for example by reducing CPU utilization and eliminating copy operations between the caches and the user buffers.
Solution
The java.base
module is modified to add a getBlockSize
method to java.nio.file.FileStore
to obtain the storage block size, and the jdk.unsupported
module (which exports the com.sun.nio.file
package) is updated to add a DIRECT
constant to ExtendedOpenOption
.
This ExtendedOpenOption::DIRECT
option may be passed to java.nio.channels.FileChannel::open
to indicate that direct I/O must be used. If the operating system or the particular file system type does not support direct I/O, then the open
will fail with an UnsupportedOperationException
.
The FileStore::getBlockSize
method allows for obtaining the block size which must be known in order to guarantee the acceptability of the channel position alignment and the alignment and size of buffers being read or written via direct I/O.
An example of the use of these new API elements is:
Path p; // initialization omitted
int blockSize = Math.toIntExact(Files.getFileStore(p).getBlockSize());
int capacity = Math.addExact(blockSize, blockSize - 1);
ByteBuffer block =
ByteBuffer.allocateDirect(capacity).alignedSlice(blockSize);
try (FileChannel fc = FileChannel.open(p, StandardOpenOption.READ,
ExtendedOpenOption.DIRECT)) {
int result = fc.read(block);
}
Throughout the implementation checks are performed to verify that the position alignment and read-write byte count constraints are met and if not an IOException
is thrown.
Specification
Public exported APIs
java.base: java.nio.file.FileStore
/**
* Returns the number of bytes per block in this file store.
*
* <p> File storage is typically organized into discrete sequences of bytes
* called <i>blocks</i>. A block is the smallest storage unit of a file store.
* Every read and write operation is performed on a multiple of blocks.
*
* @implSpec The implementation in this class throws an
* {@code UnsupportedOperationException}.
*
* @return a positive value representing the block size of this file store,
* in bytes
*
* @throws IOException
* if an I/O error occurs
*
* @throws UnsupportedOperationException
* if the operation is not supported
*
* @since 10
*/
public long getBlockSize() throws IOException {}
jdk.unsupported: com.sun.nio.file.ExtendedOpenOption
/**
* Requires that direct I/O be used for read or write access.
* Attempting to open a file with this option set will result in
* an {@code UnsupportedOperationException} if the operating system or
* file system does not support Direct I/O or a sufficient equivalent.
*
* @apiNote
* The DIRECT option enables performing file I/O directly between user
* buffers and the file thereby circumventing the operating system page
* cache and possibly avoiding the thrashing which could otherwise occur
* in I/O-intensive applications. This option may be of benefit to
* applications which do their own caching or do random I/O operations
* on large data sets. It is likely to provide the most benefit when
* the file is stored on a device which has high I/O throughput capacity.
* The option should be used with caution however as in general it is
* likely to degrade performance. The performance effects of using it
* should be evaluated in each particular circumstance.
*
* @since 10
*/
DIRECT(ExtendedOptions.DIRECT);
- csr of
-
JDK-8164900 Add support for O_DIRECT
- Resolved
- links to