java中对大文件的快速随机访问读/写访问
我正在为一个游戏创建游戏结束数据库文件。 多个线程计算游戏位置的结果,将结果保存在文件中的适当位置,但也会查阅sofar数据库以加快计算速度 到目前为止,我刚刚将一个byte[]加载到内存中,但今天早上它在试图创建一个超过Integer.MAX_值字节的文件时崩溃了java中对大文件的快速随机访问读/写访问,java,arrays,database,performance,randomaccessfile,Java,Arrays,Database,Performance,Randomaccessfile,我正在为一个游戏创建游戏结束数据库文件。 多个线程计算游戏位置的结果,将结果保存在文件中的适当位置,但也会查阅sofar数据库以加快计算速度 到目前为止,我刚刚将一个byte[]加载到内存中,但今天早上它在试图创建一个超过Integer.MAX_值字节的文件时崩溃了 我考虑两个解决方案: 使用多字节数组的包装器 随机文件存取 随机文件访问也会很好,因为它超出了我的RAM限制。 我的希望是操作系统(Windows 10/Linux Mint 20)将大部分文件加载到RAM中,这样,对于完全适合
我考虑两个解决方案:
- 使用多字节数组的包装器
- 随机文件存取
这行得通吗?或者我甚至不必麻烦了?在Java中处理大型文件的主要选项很少 美国石油学会 Pro:
- 简单,尽管是老式的API
- API调用量很大(Java调用和系统调用),从性能的角度来看,它是次优的
RandomAccesFile
相比,该类提供了面向缓冲区的API,这可能对代码的性能和组织都有好处
FileChannel
还可以配置为非阻塞IO,这对于最大化磁盘I/O非常重要
此外,FileChannel
还提供用于零拷贝数据传输文件、套接字文件、文件套接字的实用程序
内存映射缓冲区
内存映射缓冲区是通过FileChannel
提供的另一个IO选项
从理论上讲,内存映射对磁盘访问的开销可能最小,但在实践中,使用内存映射的性能与FileChannel
相当
内存映射缓冲区带来了许多问题:
- 内存映射只能由GC关闭,所以底层文件将在不可预知的时间内保持打开状态(特别是在Windows中)
- 内存映射操作导致页面错误,这会干扰JVM系统线程。因此,具有内存映射IO的应用程序经常会遇到STW暂停
- 每个内存映射缓冲区限制为2 GiB。因此,需要管理多个缓冲区。必须重用这些缓冲区,因为它们不能显式关闭
仍然提到的限制和性能优势的缺乏使得内存映射IO在Java世界中非常适合解决方案,MappedByteBuffer和RandomAccessFile都有2.1G的限制(Integer.MAX_值字节),可能是由于内部字节数组。我的诀窍是使用一种叫做记忆片段的实验材料:
看起来很好,速度也很快,但我需要向JVM中添加额外的参数:-/内存映射ByteBuffer'ss@ErwinBolwidt
ByteBuffer
使用int
偏移量-因此仍然需要在部分中完成操作系统应该像对待应用程序内存一样对待映射文件——根据需要进行分页。你是说用java的随机文件访问类读取/写入操作系统内存映射文件与读取/写入RAM中的对象差不多吗?