2012-12-16 110 views
0

使用Mapped FileChannel讀取文件似乎閃電般快......但我想知道他們是怎麼做到的?java映射FileChannel實現

他們只是在一個大的(〜64kB)緩衝區中讀取數據,然後讓我通過這個緩衝區行進?或者還有更多嗎?

我對速度印象深刻,並希望更好地理解背後的算法。

+0

這通常是因爲你的OS」 MMAP功能的支持:http://en.wikipedia.org/wiki/Mmap – jackrabbit

回答

1

內存映射,將文件映射到您的內存中,Java提供了一個庫來包裝它,以便您可以相對安全地訪問它。

它的優點包括:

  • 那裏只有一個內存拷貝,在操作系統磁盤高速緩存,並在您的應用程序(一個或多個)內存。
  • 您可以在沒有系統調用的情況下訪問文件的隨機區域。
  • Java確實限制了您可以映射的內容數量。例如,如果最大堆爲1 GB,並且最大直接內存爲1 GB,則仍然可以映射1 TB。

它的缺點包括:

  • 它消耗它不給回來,如果你重新映射或關閉文件虛擬內存。如果你有一個64位的JVM,這不是一個問題,但如果你有一個可能只有1 GB空閒的32位JVM,那麼這個問題就非常有限。它在GC運行時釋放虛擬內存。
  • 它每次讀取/寫入頁面的最小數量。如果您有很多隨機訪問,但是如果您正在讀/寫多個磁盤上的文件,實際上會減慢順序訪問,這可能很好。隨機附加多個文件一次4KB可能會導致高度碎片文件,這是不明智的。
  • 使用內存映射文件可能會更困難,使用普通的DataXxxxStream或BufferedReader/Writer。

我已經寫了一對夫婦製作存儲庫的映射文件更容易使用,我會說,當超低延遲是至關重要的,我會用它,或者你需要閱讀大量的內存,你想到會已經在磁盤緩存中,並且希望充分利用磁盤緩存。

值得注意的是,內存映射不會使磁盤子系統更快,如果這是限制因素,讀/寫數據的方式無關緊要。

+0

從Java文檔:映射的字節緩衝區和它所代表仍然有效,直到緩衝區本身是文件映射垃圾回收。你確定它從不給回虛擬內存嗎? – blackuprise

+0

@blackuprise你是對的。當不需要資源時,GC將釋放映射。 –

+0

嗨,你介意分享你的實現嗎? – Siavash

2

他們沒有讀取任何東西,直到你做了,那麼你讀的一塊基本上是通過OS分頁系統讀取。打開可能會花費你幾乎沒有什麼,但重複讀取文件的相同部分可能會導致重複的I/O。什麼都沒有免費。