Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do we need to use MappedByteBuffer.force() to flush data to disk?

I am using MappedByteBuffer to speed up file read/write operations(). My questions as below:

  1. I am not sure if I need to use .force() method to flush the content to disk or not. It seems like without .force(), the .getInt() can still work perfectly (well, since this is a memory-mapped buffer, i assume .getInt() fetches the data from disk, which means the data has been flushed into disk already.

  2. Is the .force() method a blocking method?

  3. Is a blocking method a synchronized block?

  4. There is a huge performance difference with or without calling .force() method. What's the benefit of calling .force() manually? Under which situation should we use it? I assume without calling it, the data will still be written to disk behind the scene.

  5. If we needs to call .force(), will calling it from another thread helps to improve performace? Will it corrupt the data because of synchronization problem?

    import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode;

public class Main {

public static void main(String[] args) throws IOException {
    System.out.println("start");

    RandomAccessFile raf = new RandomAccessFile("test.map", "rw");
    FileChannel fc = raf.getChannel();
    MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, 2000000);

    int total = 0;
    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 2000000; i += 4) {
        mbb.putInt(i, i);
        //mbb.force();
        total += mbb.getInt(i);
    }
    long stopTime = System.currentTimeMillis();

    System.out.println(total);
    System.out.println(stopTime - startTime);
    System.out.println("stop");
}

}

like image 494
janetsmith Avatar asked Nov 04 '10 12:11

janetsmith


People also ask

When to use memory-mapped files java?

Memory-mapped files are casual special files in Java that help to access content directly from memory. Java Programming supports memory-mapped files with java. nio package. Memory-mapped I/O uses the filesystem to establish a virtual memory mapping from the user directly to the filesystem pages.

What is memory-mapped file java?

A direct byte buffer whose content is a memory-mapped region of a file. Mapped byte buffers are created via the FileChannel. map method. This class extends the ByteBuffer class with operations that are specific to memory-mapped file regions.


2 Answers

MappedByteBuffer.force() is not useless in Windows. I used "Process Monitor" tool from http://technet.microsoft.com/en-us/sysinternals/bb896645 to monitor the file access. According to the logging, MappedByteBuffer.force() will immediately call Windows API WriteFile() in Non-cached Synchronous mode. The reliability should be similar as FileChannel.force() which will call Windows API FlushFileBuffers() immediately to write file. Therefore, MappedByteBuffer.force() is reliable enough for most kinds of usages. Tested on Windows 7 64bit with Java 1.6.0_24.

like image 60
Yao Avatar answered Sep 21 '22 11:09

Yao


  1. You should call it only if you have extreme transactional requirements, i.e. you are implementing a database. getInt() reads from memory: the operating system pages the file into and out of that memory.

  2. It is not specified.

  3. Methods are synchronized if so specified. It has nothing to do with whether they block or not.

  4. See (1). Data will still be written but at the operating system's whim rather than yours.

  5. I doubt it, but see (2), and I doubt that you need to call it at all, see (1).

like image 34
user207421 Avatar answered Sep 18 '22 11:09

user207421