Linux 中具有大量打开文件处理程序的 Java AsynchronousFileChannel
我对异步文件 I/O 的理解可能是错误的,但我尝试使用最新的 JDK 7 的 AsynchronousFileChannel 来加速应用程序,但结果却出乎意料地更糟。在我进行如下更改之前,应用程序正在使用 PrintWriter 的同步模式:
if( asynchMode ){
AsynchronousFileChannel writer = AsynchronousFileChannel.open(Paths.get(outputFileName),
StandardOpenOption.WRITE, StandardOpenOption.CREATE);
((AsynchronousFileChannel)writer).write(ByteBuffer.wrap(builder.toString().getBytes()), 0);
else{
PrintWriter writer = null;
try{
writer = new PrintWriter(new BufferedWriter(new FileWriter(
outputFileName)));
((PrintWriter)writer).write(builder.toString());
}
finally{
if( null!=writer )
writer.close();
}
}
上面的代码驻留在其自己的类中。变量asynchMode
允许我更改程序的行为。由于应用程序写入了大量确实不需要进一步验证的文件,因此我宁愿在写入文件时不让 CPU 空闲且线程等待。以上是基于我对异步文件 I/O 的理解,我承认这可能是错误的。
除了性能较差之外,还有一件奇怪的事情是,当我执行 ls -l /proc/p 时,会出现大量文件描述符。 感谢您的任何澄清和帮助!
My understanding of asynch file I/O might be wrong but I am trying to use the latest JDK 7's AsynchronousFileChannel to speed up an application with an unexpected worse result. The application was using synch mode with PrintWriter before I made the change as below:
if( asynchMode ){
AsynchronousFileChannel writer = AsynchronousFileChannel.open(Paths.get(outputFileName),
StandardOpenOption.WRITE, StandardOpenOption.CREATE);
((AsynchronousFileChannel)writer).write(ByteBuffer.wrap(builder.toString().getBytes()), 0);
else{
PrintWriter writer = null;
try{
writer = new PrintWriter(new BufferedWriter(new FileWriter(
outputFileName)));
((PrintWriter)writer).write(builder.toString());
}
finally{
if( null!=writer )
writer.close();
}
}
The above code resides in a class of its own. The variable asynchMode
allows me change the behaviour of the program. As the application writes alot of files which really need not be further validated, I would rather not let the CPU idle and the thread wait while the files are being written. The above is based on my understanding of asynch file I/O which I admit maybe on a wrong footing.
One strange thing besides poorer performance is that there is alot of file descriptors when I do a ls -l /proc/p
.
Thanks for any clarifications and help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在第一个示例中,您不关闭文件,而在第二个示例中则关闭文件。
我会确保您只测试您感兴趣的内容。否则可能是添加仅在第一种情况下执行的 getByte() 是延迟的原因。我建议您在启动计时器之前先使用 byte[] 开始,在这两种情况下进行类似比较。
注意:如果您有一个数据/文本块,使用缓冲流/编写器最多只会增加开销。
当谈到写入真实文件时,将数据写入磁盘是瓶颈。您的系统可以以许多 GB/秒的速度复制数据,但大多数旋转磁盘只能维持 50-100 MB/秒的写入速度。因此,在 Java 中稍微提高效率可能不会给您带来您想要的结果。
In the first example, you don't close the file, in the second case you do.
I would make sure you are testing only the thing you are interested in. Otherwise it could be that adding getByte() which you only do in the first case is the cause of the delay. I suggest you start with a byte[] before you start the timer in both cases for a like, for like comparison.
Note: If you have one block of data/text using a buffered stream/writer only added overhead at best.
When it comes to writing real files, it is the writing of the data to disk which is the bottle neck. Your system can copy data at many GB/s but most spinning disks can only sustain writes 50-100 MB/s. So making it slightly more efficient in Java might not give you the results you want.