我試圖在READ_WRITE模式下使用Java MappedByteBuffers來映射一個大文件(幾十GB)或一組無數小文件(〜128MB)。這是爲了實現高性能的B樹。在READ_WRITE模式下使用大量MappedByteBuffer減慢Windows 7抓取速度
我的問題是,在我的Windows 8筆記本電腦上配備8GB RAM和JDK 7時,一切都很順利,直到物理內存已滿並且操作系統開始實際將數據寫入文件。在這一點上,Windows慢慢爬行。 I/O似乎完全捱餓任何其他活動。鼠標指針幾乎不能移動,我通常最終不得不強制重新啓動機器。
下面的代碼演示了這個問題:
public static void testMap() throws Exception
{
MappedByteBuffer[] mbbs = new MappedByteBuffer[512];
for (int i = 0; i < 512; i++)
{
System.out.printf("i=%d%n", i);
RandomAccessFile raf = new RandomAccessFile(String.format("D:/testMap.%d.bin", i), "rw");
mbbs[i] = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 128*1024*1024);
for (int j = 0; j < 128*1024; j++) {
mbbs[i].put(j*1024, (byte)(i*j));
}
}
}
如果I/O的需要一定的時間,我不介意。過了一段時間,操作系統實際上必須開始將字節寫入文件。但是,在這裏,這個過程基本上使整個操作系統捱餓。我怎樣才能避免這種情況?
認識到在處理稀缺資源時會遇到資源限制很重要。是否有理由需要同時提供512個可用的內存映射文件?根據您的使用情況,您可能會採取多種不同的方法,包括集中稀缺資源(打開文件句柄)。 – allingeek
實際上,我預計文件幾乎是隨機訪問的。這就是爲什麼我希望能夠同時保留所有視圖的映射。當然,這在64位機器上似乎被認爲是可行的做法。例如,請參閱http://stackoverflow.com/questions/9261316/memory-mapped-mappedbytebuffer-or-direct-bytebuffer-for-db-implementation。它在閱讀方面工作得很好,但對寫作並不完全。我懷疑過了一段時間後,任何進程的內存訪問都會迫使操作系統將JVM進程加載的一些髒頁換掉。任何建議,以避免這種情況? – alex137
根據您希望同時訪問的文件數量,合併的解決方案可以很好地工作。使用池式方法,您可以通過改變池大小來調整性能。 無論如何,當系統內存不足時,操作系統將不得不開始交換。這就是整臺機器出現故障的原因。 – allingeek