我想象两个,但我想确认一下我是否有意义:
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...
}
答案 0 :(得分:3)
调用MappedByteBuffer.force()的正当理由是什么?
任何时候您需要将数据刷新到磁盘NOW,而不是等到缓冲区未映射或应用程序退出。
例如,使用MappedByteBuffers实现的事务数据库中的“commit”操作将要求您确保将提交的数据立即写入光盘。
[[更新
有了(重新)读取MappedByteBuffer和FileChannel的javadocs,我的结论是,在应用程序关闭时调用force()
是谨慎 ...假设你想要更新要被冲洗。据我所知,该规范不保证数据将在force()
调用的上下文中被刷新。
结束]]
我的印象是,内存映射文件被操作系统“神奇地”发送到磁盘,您无需刷新它。
这不正确。如果JVM灾难性地死亡(或kill -9
'),则无法保证刷新映射缓冲区。如果操作系统本身死亡,则更加不确定。
force()
操作适用于您需要确定的时间。如果成功,则可以保证您的更改在光盘上。
您的示例可能是合法的,也可能不是,具体取决于应用程序的详细信息。例如,在关机挂钩中执行force()
听起来有点危险。如果应用程序由于检测到内部错误而关闭,那么刷新缓冲区实际上可能会造成更多伤害......具体取决于您设计内存映射数据结构的程度。