Нужно ли использовать MappedByteBuffer.force () для сброса данных на диск? - PullRequest
10 голосов
/ 04 ноября 2010

Я использую MappedByteBuffer для ускорения операций чтения / записи файла (). Мои вопросы, как показано ниже:

  1. Я не уверен, нужно ли мне использовать метод .force () для записи содержимого на диск или нет. Кажется, что без .force (), .getInt () все еще может работать идеально (хорошо, поскольку это буфер с отображением в памяти, я предполагаю, что .getInt () извлекает данные с диска, что означает, что данные были сброшены диск уже.

  2. Является ли метод .force () методом блокировки?

  3. Является ли метод блокировки синхронизированным блоком?

  4. Существует огромная разница в производительности с или без вызова метода .force (). В чем выгода вызова .force () вручную? При какой ситуации мы должны использовать это? Я полагаю, что без вызова данные все равно будут записаны на диск за сценой.

  5. Если нам нужно вызвать .force (), поможет ли его вызов из другого потока улучшить производительность? Повредит ли это данные из-за проблем с синхронизацией?

    import java.io.FileNotFoundException; импорт java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode;

публичный класс 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");
}

}

Ответы [ 4 ]

4 голосов
/ 08 июля 2011

MappedByteBuffer.force () является , а не бесполезным в Windows. Я использовал инструмент «Process Monitor» из http://technet.microsoft.com/en-us/sysinternals/bb896645 для контроля доступа к файлам. Согласно журналу, MappedByteBuffer.force () немедленно вызовет Windows API WriteFile () в Не кэшированный синхронный режим . Надежность должна быть аналогична FileChannel.force (), которая немедленно вызовет Windows API FlushFileBuffers () для записи файла. Поэтому MappedByteBuffer.force () достаточно надежен для большинства видов использования. Протестировано на Windows 7 64bit с Java 1.6.0_24.

3 голосов
/ 04 ноября 2010
  1. Вы должны вызывать его только в том случае, если у вас есть экстремальные транзакционные требования, т.е. вы внедряете базу данных. getInt () читает из памяти: операционная система выгружает файл в память и из нее.

  2. Не указано.

  3. Методы синхронизируются, если это указано. Это не имеет никакого отношения к тому, блокируют они или нет.

  4. См. (1). Данные будут по-прежнему записываться, но по вашей прихоти операционной системы, а не по вашей.

  5. Я сомневаюсь в этом, но вижу (2), и я сомневаюсь, что вам вообще нужно это назвать, см. (1).

2 голосов
/ 04 ноября 2010

ОК, возьмите мой ответ с крошкой соли (я не эксперт NIO)

1.) putInt(i, i) запишет в MappedByteBuffer (mbb), который находится в памяти и в операционнойСистема передает это значение в фактический базовый файл (test.map), когда она этого хочет.

Использование force() сообщает операционной системе о необходимости передачи данных «сейчас» (что может быть полезно, если у вас естьдругой процесс, который должен читать из этого файла).

Ваш getInt(i) читает значение из MappedByteBuffer (mbb), если вы используете force() так, как вы, то вы знаете, что подВаш файл синхронизирован с этим буфером памяти).

Скорее всего, вам не нужно использовать force()

2.) Не уверен, я думаю это как Java 7 NIO.2 начинает ссылаться на возможность делать такие вещи неблокирующим образом.Я все еще исследую это в данный момент.

3.) Это две отдельные проблемы.Я бы посоветовал взглянуть на книгу Дуга Ли: -).

4.) Как указано в 1.), force () скажет ОС писать «сейчас», иначе ОС пишет, когда чувствуетнравится.

1 голос
/ 29 декабря 2010

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6816049

force () бесполезен в Windows. Довольно страшная ошибка.

...