"The thing that has always disturbed me about O_DIRECT is that the whole interface is just stupid, and was probably designed by aderanged
monkey on some serious mind-controlling substances [*].”[*]换句话说,这是一种Oracle主义。
- 来自Transmeta的Linus
Torvalds,2002年5月11日
检查以下内容的“注意”部分
man 2 open:
O_DIRECT
O_DIRECT标志可能对 用户空间缓冲区 的长度和地址 以及I / O 的 文件偏移量 施加对齐 限制
。在Linux中,对齐限制因文件系统和内核版本而异。在Linux 2.4下,传输大小以及用户缓冲区和文件偏移的对齐方式都必须是文件系统逻辑块大小的倍数。在Linux
2.6下,对齐到512字节边界就足够了。....总之,O_DIRECT是潜在强大的工具,应谨慎使用。建议应用程序将O_DIRECT的使用作为性能选项,默认情况下禁用。
我认为,JRE(类加载器)在FileInputStream中有一些用法,其读取的偏移量或大小未对齐512字节。(对于高级格式,最小对齐方式可能更大,甚至是4096字节或一页4K。)
内核未对齐偏移的行为是灰色区域,一些信息在这里:RFC:澄清直接I / O语义,Theodore Ts’o,tytso @
mit,LWN,2009年
其他有趣的讨论在这里:Linux:使用O_DIRECT访问文件(内核陷阱,2007年)
嗯,当DIRECT发生故障时,似乎应该回退到缓冲的I /
O。使用DIRECT的所有IO操作都是同步的。可能是某些DMA效果?或
O_DIRECT和的组合
mmap?
更新:
感谢strace输出。这是错误(
grep O_DIRECT,然后检查文件描述符操作):
28290 open("...pact/perf/TestDirectIO.class", O_RDonLY|O_DIRECT) = 1128290 fstat(11, {st_mode=S_IFREG|0644, st_size=2340, ...}) = 028290 fcntl(11, F_GETFD) = 028290 fcntl(11, F_SETFD, FD_CLOEXEC) = 0...skip28290 stat("...pact/perf/TestDirectIO.class", {st_mode=S_IFREG|0644, st_size=2340, ...}) = 0...skip28290 read(11, "312376272276 003 215n - Dt E F7 Gn 3 D10 Hn"..., 1024) = 102428290 read(11, 0x7f1d76d23a00, 1316) = -1 EINVAL (Invalid argument)未对齐的读取大小会导致
EINVAL错误。您的类文件长2340字节,它是1024 + 1316字节,未对齐。



