【发布时间】:2011-11-23 20:00:49
【问题描述】:
我有一个程序可以创建一个大小约为 50MB 的文件。在此过程中,程序经常重写文件的某些部分并强制将更改写入磁盘(大约 100 次)。它通过 fc.read(...)、fc.write(...) 和 fc.force(...) 使用 FileChannel 和直接 ByteBuffers。
新文本:
我现在对这个问题有了更好的看法。 问题似乎是我使用三个不同的 JVM 来修改一个文件(一个创建它,另外两个(从第一个启动)写入它)。在下一个 JVM 启动之前,每个 JVM 都会正确关闭文件。 问题是该文件的 fc.write() 成本偶尔会在第三个 JVM 中达到最高值(大约是正常成本的 100 倍)。也就是说,所有的写操作都同样慢,不仅仅是一个挂得很长的。 有趣的是,帮助实现这一点的一种方法是在 JVM 启动之间插入延迟(2 秒)。没有延迟,写总是很慢,有延迟,大约每秒写一次。
我还发现了这个Stackoverflow: How to unmap a file from memory mapped using FileChannel in java?,它描述了我没有使用的映射文件的问题。
我怀疑可能发生的事情: 当我调用 close() 时,Java 并没有完全释放文件句柄。当下一个 JVM 启动时,Java(或 Windows)识别对该文件的并发访问并为该文件安装一些昂贵的并发处理程序,这使得写入成本很高。 这有意义吗?
问题出现在 Windows 7(Java 6 和 7,在两台机器上测试),但在 Linux (SuSE 11.3 64) 下没有。
旧文本:
问题: 从 Eclipse 或控制台作为 JUnit 测试工具启动程序工作正常,大约需要 3 秒。 通过 ant 任务启动程序(或通过 JUnit 使用 ProcessBuilder 启动单独的 JVM)将同一任务的程序减慢到 70-80 秒(因子 20-30)。
使用 -Xprof 显示“force0”和“pwrite”的使用率从 34.1%(76+20 次)飙升至 97.3%(3587+2913+751 次): 快跑:
27.0% 0 + 76 sun.nio.ch.FileChannelImpl.force0
7.1% 0 + 20 sun.nio.ch.FileDispatcher.pwrite0
[..]
慢跑:
Interpreted + native Method
48.1% 0 + 3587 sun.nio.ch.FileDispatcher.pwrite0
39.1% 0 + 2913 sun.nio.ch.FileChannelImpl.force0
[..]
Stub + native Method
10.1% 0 + 751 sun.nio.ch.FileDispatcher.pwrite0
[..]
GC 和编译可以忽略不计。
更多事实:
没有其他方法显示 -Xprof 输出有显着变化。
- 要么快要么很慢,从不介于两者之间。
- 内存没问题,所有测试机至少8GB,进程使用
- 重启机器没有帮助
- 切换病毒扫描程序和类似的东西没有影响
- 当进程缓慢时,几乎没有 CPU 使用率
- 从普通 JVM 运行它从不慢
- 在从第一个 JVM(通过 ProcessBuilder 或作为 ant-task)启动的 JVM 中运行它时,它一直很慢
- 所有 JVM 都完全相同。我通过 RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean(); 输出 System.getProperty("java.home") 和 JVM 选项;列表参数 = RuntimemxBean.getInputArguments();
- 我在两台 Windows7 64bit、Java 7u2、Java 6u26 和 JRockit 的机器上进行了测试,虽然机器的硬件不同,但结果非常相似。
- 我也在 Eclipse(命令行 ant)外部对其进行了测试,但没有区别。
- 整个程序都是我自己写的,只是读写这个文件,没有用到其他库,尤其是没有本地库。 -
还有一些我只是拒绝相信没有任何意义的可怕事实:
- 有时(很少)删除所有类文件并重建项目会有所帮助。程序(嵌套版本)运行一到两次,然后又变得非常慢。
- 安装新的 JVM 总是有帮助的(每一次!),这样(嵌套的)程序至少可以快速运行一次!安装 JDK 算作两次,因为 JDK-jre 和 JRE-jre 都至少可以正常工作一次。重装 JVM 无济于事。重启也不行。我还没有尝试删除/重新启动/重新安装...
- 这是我设法为嵌套程序获得快速程序运行时的仅有的两种方法。
问题:
- 什么可能导致嵌套 JVM 的性能下降?
- 这些方法到底有什么作用(pwrite0/force0)? -
【问题讨论】:
标签: performance io jvm nested