我正在尝试使用FileOutputStream / BufferedOutputStream创建100个文件。 我可以看到CPU利用率是100%,持续5到10秒。我写的目录是空的。我通过iText创建PDF文件。每个文件都有1 MB的圆形。我在Linux上运行。
如何重写代码以便最大程度地降低CPU利用率?
答案 0 :(得分:8)
不要猜测:描述您的应用程序。
如果数字显示在写入调用中/内部花费了大量时间,那么请查看执行更快I / O的方法。但是如果大部分时间花在格式化输出的东西上(例如iText渲染),那么你需要集中精力。
答案 1 :(得分:4)
这是在一个已包含大量文件的目录中吗?如果是这样,您可能会看到在目录中包含大量文件的惩罚 - 这在操作系统和文件系统中会有很大差异。
否则,在创建文件时,您实际在做什么?数据来自哪里?它们是大文件吗?您可能想要做的一件事是尝试写入ByteArrayOutputStream
- 这样您就可以看到有多少活动是由文件系统引起的,以及您获取/写入数据的方式。
答案 2 :(得分:2)
这是一个长镜头猜测,但即使你使用缓冲流,也要确保你不是一次写出一个字节。
.read(int)
和.write(int)
方法是CPU杀手。您应该使用.read(byte[]...)
和.write(byte[], int, int)
来确定。
答案 3 :(得分:0)
您不太可能减少任务的CPU负载,尤其是在Windows系统上。 Linux上的Java确实支持异步文件I / O,但这会使代码严重复杂化。我怀疑你在Windows上运行,因为文件I / O通常在Windows上花费的时间比在Linux上花费的时间多得多。我甚至在Windows上的Linux VM中运行Java时听说过改进。
在流程运行时查看任务管理器,然后启用显示内核时间。通常可以优化在用户空间中花费的CPU时间,但通常只能通过更有效的调用来减少内核空间中的CPU时间。
JSR 203专门解决了对异步,多路复用,分散/收集文件IO的需求:
JSR-51引入的多路复用非阻塞工具解决了网络套接字的大部分问题,但它没有为文件系统操作做到这一点。
在JSR-203成为Java的一部分之前,您可以通过Linux上的Apache MINA项目获得真正的异步IO。
Java NIO(1)允许您执行基于通道的I / O.这是性能的改进,但你一次只做一个数据缓冲,而不是真正的async&多路复用IO。
答案 4 :(得分:0)
要写入的1MB文件足够大,可以使用java.nio
FileChannel,并且可以比java.io
看到更大的性能提升。重写你的代码,并测量它对旧的东西。我预测至少会有2倍的改善。