我正在編寫一個Android應用程序。據我所知,設備中的大多數SD卡都具有〜4Mb/s的寫入速度。在最糟糕的情況下,我的應用程序需要創建一個約0.5Mb的新文件並將其寫入約5次。一般來說,這樣做時IO速度非常快,但是在短時間內創建並寫入多個文件後,我經歷了大約2秒的突然等待時間。定期寫入數據時隨機長時間IO暫停
下面是我的應用程序的一些統計數據(注意,只有一個IO操作在時間永遠跑):
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 <--
注意,大部分的IO操作的完成在< 0.05秒,但是,在大約8寫操作總共寫入約4Mb的數據,下一次IO操作需要約1.5s。這是爲什麼發生?這種模式發生得相當一致。
我的文件正被寫入下面的代碼(我不沖洗或同步):
RandomAccessFile fos = new RandomAccessFile(filename, "rw");
FileChannel outChannel = fos.getChannel();
byteBuffer.rewind();
outChannel.write(byteBuffer);
fos.close();
我在文件IO方面的專家,但我知道快速IO操作次數指明的不是招數據實際上還沒有寫入磁盤,大的暫停可能是緩衝區被刷新。我如何避免暫停?看起來好像我的IO操作很小且不經常發生,所以我應該能夠避免這種暫停。
對於某些上下文:我使用帶紀念品的命令模式在用戶可以執行許多破壞性操作的上下文中實現撤銷/重做。我無法將記憶存儲在內存中,因爲我沒有足夠的內存,所以我會將記錄寫入磁盤。除了上述暫停問題之外,這種方法非常棒,因爲這意味着用戶界面不得不等待IO完成,並且1.5秒的滯後對用戶來說太隱蔽了。我知道還有其他的是實施撤消/重做,但每種方法都有缺陷。
呃,這很令人失望。我希望我的撤銷/重做堆棧在應用程序會話之間持續存在,因此我需要在某個時刻將這些堆棧保存到磁盤。命令對象也可以增長到相當大的尺寸,所以我需要有一個後臺進程將它們寫入磁盤,因爲它們是創建的。儘管IO寫入次數不可預知,但如何在我的應用程序被中斷的情況下確保在onPause被調用的時候確保將所有寫入磁盤的內容都不明確。如果我需要在每個文件上調用.sync(),情況會更糟。有什麼建議? – rbcc 2011-02-02 01:13:28