MappedByteBuffer滑动窗口

6
有没有办法让MappedByteBuffer在文件上拥有滑动窗口?我的文件非常大(20GB),但我每次只想处理100MB。我尝试过仅丢弃旧的缓冲区并从通道创建新的缓冲区,但由于旧的缓冲区似乎无法被重用,这会占用内存。请问有什么好的建议吗?
1个回答

3
你可以使用以下方法强制释放旧缓冲区的内存:
((DirectBuffer) buffer).cleaner().clean();

免责声明:我只在Sun/Oracle/OpenJDK Java 6更新18及更高版本中使用过此功能。它可能在旧版本或其他平台上不可用或无法正常工作。感谢 @EJP。
除非您使用的是32位操作系统,否则我建议将整个文件映射到内存中(使用多个映射)。这样更有效率且更易于管理。在这种情况下,我只在关闭文件时(在单元测试中)清理ByteBuffer。
您可以使用TB级别的虚拟内存,并使用极少量的物理甚至磁盘空间。在此示例中,我将8 TB的虚拟内存映射到具有24 GB内存和120 GB驱动器的计算机上。

http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html

总之,在64位计算机上,虚拟内存非常便宜,这不是你需要担心的事情。
顺便说一下:大多数64位计算机实际上仅限于48位虚拟内存。这是256 TB的限制,而不是它们在理论上可以寻址的16 EB(18,000,000 TB)。
你可能会对这个库感兴趣。我之前没有提到它,因为它可能不适合你,但你可能会发现其中的方法和技巧很有趣。

https://github.com/peter-lawrey/Java-Chronicle


你应该声明DirectBuffer和其他在此处被依赖的类都是sun.misc.*类,因此受到通常警告的限制。我最初是在1.4版本中看到所有这些内容的:它现在真的还能用吗? - user207421
@EJP,正如您所指出的那样,它不适用于所有系统。但是,在Sun/Oracle和OpenJDK JVM上至少可以很好地工作。我已经在生产中使用这种方法约两年(并且有两份不同的工作)。 - Peter Lawrey
最早的版本是Java 6 update 18,最新的是Java 7 update 3。有趣的问题是它是否适用于所有具有NIO(从Java 1.4开始)的版本。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接