Случайные длинные IO паузы при периодической записи данных - PullRequest
3 голосов
/ 02 февраля 2011

Я пишу приложение для Android.Насколько я знаю, большинство SD-карт в устройствах имеют скорость записи ~ 4 Мбит / с.В худшем случае мое приложение должно создавать и записывать ~ 0,5 Мбайт в новый файл примерно 5 раз в секунду.Как правило, ввод-вывод выполняется очень быстро, но после создания и записи в несколько файлов за короткий промежуток времени у меня возникает неожиданно большое время ожидания ~ 2 секунды.

Вот некоторые статистические данные из моего приложения(обратите внимание, что одновременно выполняется только одна операция ввода-вывода):

E  = Time IO operation began
S  = Number of Mbs written
WT = Time taken to write to file

E      S        WT     
14.546 ~0.41 MB 0.02s
15.061 ~0.40 MB 0.019s
15.600 ~0.42 MB 0.073s
16.054 ~0.41 MB 0.02s
16.538 ~0.36 MB 0.019s
17.007 ~0.33 MB 0.018s
17.475 ~0.32 MB 0.017s
18.030 ~0.38 MB 0.07s
19.991 ~0.38 MB 1.542s <--
20.124 ~0.34 MB 0.018s
20.233 ~0.25 MB 0.015s
20.390 ~0.38 MB 0.021s
20.624 ~0.36 MB 0.08s
20.858 ~0.37 MB 0.018s
21.304 ~0.32 MB 0.018s
21.796 ~0.33 MB 0.017s
22.257 ~0.35 MB 0.02s
22.780 ~0.37 MB 0.07s
24.366 ~0.27 MB 1.178s <--
24.522 ~0.40 MB 0.021s
24.648 ~0.34 MB 0.019s
24.866 ~0.38 MB 0.018s
25.319 ~0.29 MB 0.07s
25.850 ~0.45 MB 0.021s
26.288 ~0.39 MB 0.018s
26.796 ~0.43 MB 0.035s
27.249 ~0.33 MB 0.069s
27.671 ~0.41 MB 0.018s
30.054 ~0.44 MB 1.874s <--

Обратите внимание, что большинство операций ввода-вывода завершается за <0,05 с, но после примерно 8 операций записи, когда было ~ 4 МБ данныхв общей сложности следующая операция ввода-вывода занимает ~ 1,5 с.Почему это происходит?Этот шаблон происходит довольно последовательно. </p>

Мои файлы пишутся с использованием следующего кода (я не сбрасываю или синхронизирую):

  RandomAccessFile fos = new RandomAccessFile(filename, "rw");
  FileChannel outChannel = fos.getChannel();
  byteBuffer.rewind();
  outChannel.write(byteBuffer);
  fos.close();

Я не эксперт в области файлового ввода-вывода, но язнать, что быстрое время операций ввода-вывода указывает на то, что данные на самом деле еще не записаны на диск, и большие паузы, вероятно, представляют собой сбрасываемые буферы.Как мне избежать пауз?Кажется, что мои операции ввода-вывода являются небольшими и достаточно редкими, чтобы я мог избежать этой паузы.

Для некоторого контекста: я использую шаблон команды с mementos для реализации отмены / повторения в контексте, гдеПользователь может выполнять множество разрушительных операций.Я не могу сохранить сувениры в памяти, потому что у меня недостаточно памяти, поэтому я вместо этого записываю сувениры на диск.Это работает фантастически, за исключением описанной выше проблемы с паузой, поскольку это означает, что пользовательский интерфейс вынужден ждать завершения ввода-вывода, а задержка в 1,5 с слишком велика, чтобы скрывать ее от пользователя.Я знаю, что есть другие, чтобы реализовать отмену / повтор, но у каждого подхода есть недостатки.

1 Ответ

3 голосов
/ 02 февраля 2011

Почему это происходит?

Добро пожаловать на флэш-память.

Я не специалист в области файлового ввода-вывода, но я знаю, что быстрое время операции ввода-вывода указываетна самом деле данные еще не были записаны на диск, и большие паузы, вероятно, являются сбрасываемыми буферами.

Вероятно, нет.Большинство Android-устройств используют файловую систему YAFFS2, которая, как я понимаю, не слишком сильно буферизует данные.Тем не менее, они имеют блокировку записи для каждого раздела, поэтому ваши паузы, вероятно, возникают, когда что-то записывает во флэш-память.

Чем больше устройств Android (например, Nexus S) запускают файловую систему ext4, то очистка / синхронизация становятся важными .

Также имейте в виду, что скорость записи во флэш-память будет зависеть от множества других факторов, таких как степень заполнения файловой системы, состояние выравнивания износа приконкретные ячейки и т. д.

Возможно, вы захотите посмотреть презентацию Брэда Фицпатрика 2010 Google I | O"Написание приложений для Zippy Android", поскольку он более подробно расскажет об этом.

Как мне избежать пауз?

Вы этого не делаете.Вы перемещаете флэш-ввод / вывод в фоновый поток, возможно, через AsyncTask.Новый StrictMode в Android 2.3 поможет вам определить, где у вас есть такой «джанки» код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...