私はAndroidアプリケーションを作成しています。私が知る限り、デバイスのほとんどのSDカードは〜4Mb/sの書き込み速度を持っています。最悪の場合、私のアプリケーションでは、1秒あたり約0.5回、新しいファイルに〜0.5MBを作成して書き込む必要があります。一般的に、これを実行するとIOは非常に高速ですが、短時間にいくつかのファイルを作成して書き込んだ後、突然の待ち時間が〜2秒になります。ここで 定期的にデータを書き込むときにランダムな長いIOが一時停止する
が自分のアプリケーションからいくつかの統計です(唯一のIO操作が今まで一度に実行されていることに注意してください):IO操作のほとんどはなく、< 0.05sで終了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 <--
お知らせを、約8後〜4Mbのデータが合計で書き込まれている場合、次のIO操作は約1.5秒かかります。なぜこうなった?このパターンはかなり一貫して起こります。
私のファイルは、(私がフラッシュしたり同期していないよ)次のコードで書かれている:
RandomAccessFile fos = new RandomAccessFile(filename, "rw");
FileChannel outChannel = fos.getChannel();
byteBuffer.rewind();
outChannel.write(byteBuffer);
fos.close();
私は、ファイルIOには専門家だが、私は、高速IO操作時間がhasnデータを示している知っています実際にはまだディスクに書き込まれていません。大きな休止はおそらくバッファがフラッシュされることでしょう。一時停止を避けるにはどうしたらいいですか?私のIO操作が小さくて、まれにこの一時停止を避けることができるはずです。
いくつかのコンテキストでは、私はmementosでコマンドパターンを使用して、ユーザーが実行できる破壊的操作が多いコンテキストでアンドゥ/リドゥを実装しています。私は記憶が足りないので記憶に記憶を保存することができないので、代わりに記憶をディスクに書き込む。これは、上記の一時停止の問題を除いて素晴らしいことです。これは、UIがIOの終了を待つことを余儀なくされ、遅延の1.5秒がユーザーから隠れるには多すぎることを意味します。私は、取り消し/やり直しを実装することが他にもあると知っていますが、すべてのアプローチには欠陥があります。
ああ、残念です。私は私の元に戻す/アプリケーションセッションの間に維持するためにスタックをやり直したいので、これらのスタックをある時点でディスクに保存する必要があります。コマンドオブジェクトはかなりの大きさに成長するので、作成されたときにディスクに書き込むバックグラウンドプロセスが必要になります。しかし、予想外のIO書き込み時間では、アプリケーションが中断された場合にonPauseが呼び出されるまでに、すべてのものをディスクに書き込むようにする方法がわかりません。 .sync()を各ファイルで呼び出す必要がある場合は、状況はさらに悪化します。何かアドバイス? – rbcc
@rebeccamaher:「コマンドオブジェクトはかなり大きなサイズに成長するので、バックグラウンドプロセスを作成してディスクに書き込む必要があります。」 - 背景*糸*してください。 'LinkedBlockingQueue'を使用して、キュー上のメモを受け取ったスレッドが到着したときにフラッシュに書き込むことを検討してください。 「アプリケーションが中断された場合にonPauseが呼び出されるまでに、すべてのものをディスクに書き込むようにする方法を明確にすることはできません」 - バックグラウンドスレッドは 'onPause()'の呼び出しによって影響を受けません。 – CommonsWare
おっと、私はスレッドを意味しました。参照ありがとう!別のアクティビティが前面に来たときにスレッドを実行する際に問題はありませんか?スレッドが殺される可能性はありませんか?ヒントをありがとう、私はこのアイデアを試すことができます。私の唯一の問題は、データをディスクに保存することができない場合、私はあまりにも多くのコマンドを投げ捨てる必要がないように、保存するデータを最小限に抑えることです。 – rbcc