java - 调用 MappedByteBuffer.force() 的正当理由是什么?

标签 java memory io real-time nio

我想象有两个,但我想确认我在这里是否有意义:

1) JVM 因未捕获的异常而退出 => 这里可能是错误的,因为退出的 JVM 会以某种方式为我执行此操作,但为了安全起见,在 ShutdownHook 中自己执行此操作不会有什么坏处。

2) 如果我必须“滚动”ByteBuffer,这意味着它将超出容量,我需要一个新的 => 我正在考虑在即将满的那个上调用force(),然后丢弃它,然后创建从文件末尾开始一个新的。

理想的解决方案是拥有一个永远不会超出容量的 ByteBuffer,但我想检查这种情况并滚动字节缓冲区。

那么你认为在上述情况下我应该调用force()吗?我可以丢弃 ByteBuffer 并使用 file.length() 打开一个新的,而不对前一个 ByteBuffer 调用 force() 吗?

这是我的flush方法的代码:

        if (isMemoryMapped) {

            // first test if we are approaching the limit...
            int cap = buffer.capacity();
            int pos = buffer.position();
            float usage = (float) pos / cap;

            if (usage >= Log.getMappedBufferThreshold()) {
                // roll our buffer
                MappedByteBuffer mappedBuffer = (MappedByteBuffer) buffer;
                mappedBuffer.force();
                this.buffer = this.createMappedByteBuffer(outputFile, getMappedBufferSize());
            }

            // Then do NOTHING since this is a memory mapped buffer...

        }

最佳答案

What are the legitimate reasons to call MappedByteBuffer.force()?

任何时候您需要立即将数据刷新到磁盘,而不是等到缓冲区取消映射或应用程序退出。

例如,使用 MappedByteBuffers 实现的事务数据库中的“提交”操作将要求您确保提交的数据立即写入光盘。

[[ 更新

(重新)阅读 MappedByteBuffer 和 FileChannel 的 javadocs 后,我的结论是,在应用程序关闭时调用 force() 也是谨慎的...假设您希望刷新更新。据我所知,该规范不保证数据将在 force() 调用的上下文中刷新。

END]]

My impression is that Memory Mapped Files are "magically" sent to disk by the OS and you do NOT have to flush it.

这是不正确的。如果 JVM 灾难性地终止(或被 kill -9 'ed),则无法保证映射的缓冲区将被刷新。操作系统本身是否死掉就更不确定了。

force() 操作适用于需要确定性的情况。如果成功,则保证您的更改已保存在光盘上。

您的示例可能合法,也可能不合法,具体取决于应用程序的详细信息。例如,在 shutdown hook 中执行 force() 听起来有点危险。如果应用程序因为检测到内部错误而关闭,那么刷新缓冲区实际上可能会造成更大的危害......具体取决于您设计内存映射数据结构的程度。

关于java - 调用 MappedByteBuffer.force() 的正当理由是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9961422/

相关文章:

Python - Pandas 输出限制列

java - 如何制作像 WhatsApp 聊天 Activity 一样的 RecyclerView?

java - 无法使用 Java 和 Selenium Webdriver 单击按钮

ios - HERE map ios 的内存压力

python - 与 CPython 相比,PyPy 占用大量内存

c++ - 将 float 写入和读取二进制文件时的不同值

java - 如何使用固定输入创建 GraphServiceClient 的 IAuthenticationProvider 对象

java - 将历史记录存储在数据库中

linux - 如何找出 Linux 中哪些进程正在使用交换空间?

c - 在函数内部分配内存并将其返回