有没有人对此进行过基准测试?我想尽可能快地写入磁盘,最大限度地减少写入调用的延迟。我想知道写入内存映射缓冲区(通过buffer.put())是否比仅缓冲Java端的内容更快,而只是在缓冲区已满时刷新到fileChannel。这样,一旦缓冲区变满,我就会进行系统调用(FileChannel.write)。我不确定当我向MappedByteBuffer写一些字节时会发生什么,换句话说,如果系统调用完成了。
使用缓冲方法,我将能够以16,32或64k的块写入磁盘,我认为这是最佳的。缓冲的缺点是,如果应用程序崩溃,您必须有一个关闭挂钩来刷新内容。还有一层复制到缓冲区,而不是直接写入文件通道。如果你拖尾文件,你可能看不到你想要的东西,因为内容是缓冲的。我也不知道如果你拖尾一个内存映射文件会发生什么。
任何有经验的灵魂都可以在这里帮忙吗?
答案 0 :(得分:4)
如果您正在尝试最小化延迟,我发现写入MemoryMappedFiles更快,因为它避免需要进行系统调用。这假设您不需要将数据强制到磁盘,并且很乐意操作系统尽力执行此操作。
写入MemoryMappedFile的典型延迟与写入内存相同,所以我不相信你会更快。随着文件的增长,您需要执行额外的内存映射区域,这可能需要50到100微秒,这是重要的,但应该非常罕见,无关紧要。
通过系统调用写入IO大约需要5到10微秒,这对于更多应用程序来说足够快,但如果重要的话,则相对慢得多。
如果您需要查看数据,因为它是以低延迟编写的,我建议您查看我的库Java Chronicle,它支持从写入时起以100 ns的典型延迟读取数据
注意:虽然内存映射文件可以减少单个写入的延迟,但它不会增加磁盘子系统的写入吞吐量。这意味着如果你的磁盘子系统速度很慢,你的内存很快就会耗尽(即使你有很多GB),无论采用哪种方法,这都会成为性能瓶颈。
例如,如果您有SATA或光纤,则可能有500 MB / s的限制,这很容易超过,在这种情况下,一旦达到内存限制,无论您选择什么,这都会降低您的速度。