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

时间:2012-04-01 02:23:00

标签: java memory io real-time nio

我想象两个,但我想确认一下我是否有意义:

1)JVM退出未捕获的异常=>可能在这里错了,因为不知何故现有的JVM会为我做这件事,但是安全并且在ShutdownHook中自己做也不会有害。

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

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

所以你觉得我应该在上面的情况下调用force()吗?我可以丢弃ByteBuffer并使用file.length()打开一个新的,而不调用前一个上的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...

        }

1 个答案:

答案 0 :(得分:3)

  

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

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

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

[[更新

有了(重新)读取MappedByteBuffer和FileChannel的javadocs,我的结论是,在应用程序关闭时调用force()谨慎 ...假设你想要更新要被冲洗。据我所知,该规范不保证数据将在force()调用的上下文中被刷新。

结束]]

  

我的印象是,内存映射文件被操作系统“神奇地”发送到磁盘,您无需刷新它。

这不正确。如果JVM灾难性地死亡(或kill -9'),则无法保证刷新映射缓冲区。如果操作系统本身死亡,则更加不确定。

force()操作适用于您需要确定的时间。如果成功,则可以保证您的更改在光盘上。

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