JohnPristine
JohnPristine

Reputation: 3575

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

I imagine two, but I would like to confirm if I am making sense here:

1) JVM exiting on an uncaught exception => probably wrong here since somehow the exiting JVM will do that for me, but it would not hurt to be safe and do it yourself inside a ShutdownHook.

2) If I have to "roll" the ByteBuffer, meaning it will go over capacity and I need a new one => I am thinking about calling force() on the one that's getting full, then discard it, then create a new one starting in the end of the file.

The ideal solution would be to have a ByteBuffer that would NEVER go over capacity, but I want to check for this scenario and roll the byte buffer.

So do you think I should call force() in the situations above? Can I just discard the ByteBuffer and open a new one using file.length() without calling force() on the previous one?

Here is my code for my flush method:

        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...

        }

Upvotes: 2

Views: 653

Answers (1)

Stephen C
Stephen C

Reputation: 719679

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

Any time that you need the data to be flushed to disk NOW, rather than waiting until the buffer is unmapped or the application exits.

For example, the "commit" operation in a transactional database implemented using MappedByteBuffers would require you to ensure that the committed data gets written to the disc immediately.

[[ UPDATE

Having (re-)read the javadocs for MappedByteBuffer and FileChannel, my conclusion is that it is prudent to call force() on application shutdown too ... assuming that you want the updates to be flushed. As far as I can tell, the spec provides no guarantees that data will be flushed apart from in the context of a force() call.

END ]]

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

That's not correct. If the JVM dies catastrophically (or is kill -9 'ed) then there is no guarantee that mapped buffers will be flushed. It is even more uncertainty if the operating system itself dies.

The force() operation is for when you need certainty. If it succeeds, you are guaranteed that your changes are on disc.

Your examples may be legitimate, or not depending on the details of the application. For instance, doing a force() in shutdown hook sounds a bit dangerous. If the application is shutting down because it has detected an internal error, then flushing the buffer could actually do more harm ... depending on how well you've designed your memory mapped data structures.

Upvotes: 3

Related Questions