Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 多个JVM的I/O性能(受Windows 7影响,Linux工作)_Performance_Io_Jvm_Nested - Fatal编程技术网

Performance 多个JVM的I/O性能(受Windows 7影响,Linux工作)

Performance 多个JVM的I/O性能(受Windows 7影响,Linux工作),performance,io,jvm,nested,Performance,Io,Jvm,Nested,我有一个程序可以创建一个大约50MB大小的文件。在这个过程中,程序经常重写文件的各个部分,并强制将更改按100次的顺序写入磁盘。它通过fc.read…,fc.write…,使用文件通道和直接字节缓冲区。。。和fc.force 新案文: 我现在对这个问题有了更好的看法。 问题似乎是我使用了三个不同的JVM来修改一个文件,一个创建了它,另两个从第一次写入开始启动。在启动下一个JVM之前,每个JVM都会正确关闭文件。 问题是第三个JVM写入该文件的fc.write成本有时会超过正常成本的100倍。也就

我有一个程序可以创建一个大约50MB大小的文件。在这个过程中,程序经常重写文件的各个部分,并强制将更改按100次的顺序写入磁盘。它通过fc.read…,fc.write…,使用文件通道和直接字节缓冲区。。。和fc.force

新案文:

我现在对这个问题有了更好的看法。 问题似乎是我使用了三个不同的JVM来修改一个文件,一个创建了它,另两个从第一次写入开始启动。在启动下一个JVM之前,每个JVM都会正确关闭文件。 问题是第三个JVM写入该文件的fc.write成本有时会超过正常成本的100倍。也就是说,所有写操作都同样慢,不仅仅是一个挂起时间很长的操作。 有趣的是,帮助实现这一点的一种方法是在JVM启动之间插入2秒的延迟。没有延迟,写作总是很慢,有延迟,写作大约每秒钟慢一次

我还发现这描述了映射文件的一个问题,我没有使用它

我怀疑可能发生了什么: 当我调用close时,Java并没有完全释放文件句柄。当下一个JVM启动时,Java或Windows会识别对该文件的并发访问,并为该文件安装一些昂贵的并发处理程序,这使得编写变得昂贵。 这有意义吗

该问题发生在Windows 7 Java 6和7上,在两台机器上进行了测试,但在Linux SuSE 11.3 64下没有

旧文本:

问题是: 从eclipse或控制台作为JUnit测试工具启动程序效果良好,大约需要3秒钟。 通过ant任务或通过JUnit启动程序(通过使用ProcessBuilder启动单独的JVM),对于相同的任务系数20-30,程序的速度会降低到70-80秒

使用-Xprof可以发现“force0”和“pwrite”的使用从34.1%76+20 tics到97.3%3587+2913+751 tics的使用范围非常广泛: 快速运行:

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,进程使用您是否使用本地磁盘进行所有测试,而不是任何网络共享

你能用ram驱动器设置Windows来存储数据吗?当JVM终止时,默认情况下它的文件句柄将被关闭,但您可能看到的是数据被刷新到磁盘上。当您覆盖大量数据时,先前版本的数据将被丢弃,并且可能不会导致磁盘IO。关闭文件的行为可能会使windows内核隐式地将数据刷新到磁盘。因此,使用ram驱动器将允许您确认其自磁盘IO时间已从您的统计数据中删除

找到一个windows工具,它允许您强制内核将所有缓冲区刷新到磁盘,在JVM运行之间使用它,看看这需要多长时间

但我猜您在尝试管理磁盘块缓冲区缓存时,遇到了进程的需求和内核的需求。在linux中,有一个像/sbin/blockdev-flushbufs这样的工具可以做到这一点

FWIW

pwrite是一个Linux/Unix API,它允许并发写入文件描述符,这将是JVM使用的最好的内核系统调用API。我认为Win32 API已经为在进程中的线程之间共享文件句柄提供了相同的用途,但由于Sun有Unix heritige,因此以Unix方式命名。有关此API的更多信息,请使用谷歌pwrite2


force我猜这是一个文件系统同步,这意味着该过程要求内核将当前在磁盘块缓冲区缓存中的未写入数据刷新到磁盘上的文件中,就像关闭计算机之前需要的那样。此操作将随时间自动发生,但事务系统需要知道以前使用pwrite写入的数据何时实际到达物理磁盘并存储。因为其他一些磁盘IO依赖于知道这一点,例如事务检查点。

您是否使用本地磁盘进行所有测试,而不是任何网络共享

你能用ram驱动器设置Windows来存储数据吗?当JVM终止时,默认情况下它的文件句柄将被关闭,但您可能看到的是数据被刷新到磁盘上。当您覆盖大量数据时,先前版本的数据将被丢弃,并且可能不会导致磁盘IO。关闭文件的行为可能会使windows内核隐式地将数据刷新到磁盘。因此,使用ram驱动器将允许您确认其自磁盘IO时间已从您的统计数据中删除

找到一个windows工具,它允许您强制内核将所有缓冲区刷新到磁盘上,在JVM运行之间使用它 你看,那要花多长时间

但我猜您在尝试管理磁盘块缓冲区缓存时,遇到了进程的需求和内核的需求。在linux中,有一个像/sbin/blockdev-flushbufs这样的工具可以做到这一点

FWIW

pwrite是一个Linux/Unix API,它允许并发写入文件描述符,这将是JVM使用的最好的内核系统调用API。我认为Win32 API已经为在进程中的线程之间共享文件句柄提供了相同的用途,但由于Sun有Unix heritige,因此以Unix方式命名。有关此API的更多信息,请使用谷歌pwrite2


force我猜这是一个文件系统同步,这意味着该过程要求内核将当前在磁盘块缓冲区缓存中的未写入数据刷新到磁盘上的文件中,就像关闭计算机之前需要的那样。此操作将随时间自动发生,但事务系统需要知道以前使用pwrite写入的数据何时实际到达物理磁盘并存储。因为其他一些磁盘IO依赖于知道这一点,例如事务性检查点。

一件有帮助的事情是确保将FileChannel显式设置为null。然后在程序结束时调用System.runFinalization和System.gc。您可能需要一个以上的电话


System.runFinalizersOnExittrue也可能有帮助,但它已被弃用,因此您必须处理编译器警告。

有一点可以帮助您确保显式将FileChannel设置为null。然后在程序结束时调用System.runFinalization和System.gc。您可能需要一个以上的电话

System.runFinalizersOnExittrue也可能有帮助,但它已被弃用,因此您必须处理编译器警告