Netty架構 - nio - 內存映射文件

Memory Mapped File

在java早期版本中,使用FileSystem傳統的API來訪問系統文件。這種場景下,JVM發起read()、write()系統調用從OS kernel到JVM傳輸數據。JVM使用它的內存空間加載、處理文件。如果文件比較大,處理起來比較慢。OS使用的方式處理文件,而JVM使用字節流的方式,不能匹配文件頁,因此需要從OS內核空間拷貝文件的內容到JVM空間。從jdk1.4開始,提供了MappedByteBuffer,用於幫助建立一個從JVM空間到OS文件系統頁的映射的虛擬內存。這種方式避免了因爲拷貝文件內容的帶來的開銷。OS使用虛擬內存在內核空間之外緩存文件,可以被非內核進行所共享。java直接映射文件頁到MappedByteBuffer,然後處理文件,不需要將其加載到JVM裏面。請添加圖片描述

MappedByteBuffer直接使用FileChannelmap方法,對虛擬內存的內容進行映射。MappedByteBuffer對象工作起來像buffer,但是它的數據存儲在虛擬內存的文件裏。get()方法可以從文件裏獲取數據。put()方法更新數據,對文件的其他讀者修改可見。

這樣做的好處,如下:

  • JVM直接在虛擬內存上處理,不需要發起read()、write()系統調用。
  • JVM不需要在它的內存空間中加載文件,處理大數據文件更有效率。
  • OS基本上只需要關注虛擬內存的讀寫,不需要使用JVM。
  • 提供文件的部分映射。
  • 虛擬內存的文件數據不需要buffer進行傳遞。

在這裏插入圖片描述

在這裏插入圖片描述

如果增加了準備寫入的文件大小,並且大於了文件本身的大小,導致MappedByteBuffer 在寫模式中匹配的大小變得更大,但是在讀模式中會拋出IOException。

提供瞭如下三種映射模式:

  • READ_ONLY: Read only
  • READ_WRITE: Read and update the file
  • PRIVATE: Change in MappedByteBuffer will not reflect to File.

映射同一個文件的多個MappedByteBuffer之間不可見可以通過PRIVATE映射模式,創建私有的副本。

如果在READ_ONLY模式中寫,會拋出NonWritableChannelException。如果讀取的channel沒有開放,此時的讀取會拋出NonReadableChannelException。

e.g.

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章