[英]Why mmap() (Memory Mapped File) is faster than read()
我最近正在研究Java NIO的MappedByteBuffer。 我已經閱讀了一些關於它的帖子,所有人都提到“mmap()比read()更快”
在我的結論中:
我對待MappedByteBuffer == Memory Mapped File == mmap()
read()必須通過以下方式讀取數據:磁盤文件 - >內核 - >應用程序,因此它具有上下文切換和緩沖區復制
他們都說mmap()比read()具有更少的復制或系統調用,但據我所知,它還需要在您第一次訪問文件數據時從磁盤文件中讀取。 所以第一次讀它:虛擬地址 - >內存 - >頁面錯誤 - >磁盤文件 - >內核 - >內存。 除了你可以隨機訪問它,最后3個步驟(磁盤文件 - >內核 - >內存)與read()完全相同,那么mmap()如何比read()更少復制或系統調用?
mmap()和交換文件之間的關系是什么,os是否會將最少使用的內存文件數據放入交換(LRU)? 因此,當您第二次訪問這些數據時,操作系統會從交換但不是磁盤文件中檢索它們(不需要復制到內核緩沖區),這就是為什么mmap()復制和系統調用較少的原因?
在java中,MappedByteBuffer是從堆中分配的(它是一個直接緩沖區)。 所以當你從MappedByteBuffer中讀取時,是否意味着它需要從Java堆外部再添加一個額外的內存副本到java堆中?
誰能回答我的問題? 謝謝 :)
1:是的,這基本上就是MappedByteBuffer。
2:“磁盤文件 - >內核”不一定涉及復制。
3:使用內存映射文件,一旦內核將文件讀入其緩存,它就可以簡單地將緩存的那部分映射到您的進程中 - 而不必將數據從緩存復制到您的進程指定的位置。
4:如果內核決定從內存映射文件中換出頁面,它將不會將頁面寫入頁面文件; 在丟棄頁面之前,它會將頁面寫入原始文件(從中映射的文件)。 將其寫入頁面文件將是不必要的並浪費頁面文件空間。
5:是的。 例如,如果調用get(byte[])
則數據將從堆外映射復制到數組中。 請注意,諸如get(byte[])
函數需要復制任何類型緩沖區的數據 - 這不是特定於內存映射文件的。
你在比較蘋果和橘子。 mmap()
'比read()
更快,因為它不執行任何I / O. 當您訪問由映射產生的內存地址時,I / O將延遲到。 該 I / O是一樣一樣read(),
並且不管是 I / O快於read()
是一個很有爭議的問題。 在我接受之前,我希望看到一個合適的基准。
我對待
MappedByteBuffer
== Memory Mapped File ==mmap()
好。
read()
必須通過以下方式讀取數據:磁盤文件 - >內核 - >應用程序,因此它有兩次上下文切換和緩沖區復制
相比什么?
他們都說mmap()比
read(),
有更少的復制或系統調用read(),
它具有較少的系統調用。 它是否具有較少的復制取決於實現。 當然可以通過DMA直接讀取和寫入數據,但特定的操作系統是否是特定於操作系統的。
但據我所知,它還需要在您第一次訪問文件數據時從磁盤文件中讀取。
正確。
所以第一次讀它:虛擬地址 - >內存 - >頁面錯誤 - >磁盤文件 - >內核 - >內存。 除了你可以隨機訪問它,最后3個步驟(磁盤文件 - >內核 - >內存)與read()完全相同,那么mmap()如何比read()更少復制或系統調用?
因為DMA,如果實現的話。
mmap()和交換文件之間的關系是什么
分配給映射的內存是進程地址空間的一部分,它是虛擬的,並且需要進行交換,並且交換文件中必須有空間,就像任何其他內存一樣。
是os將把最少使用的內存文件數據放入交換(LRU)?
沒有。
因此,當您第二次訪問這些數據時,操作系統會從交換但不是磁盤文件中檢索它們(不需要復制到內核緩沖區),這就是為什么mmap()復制和系統調用較少的原因?
不。做所有這些都是錯的。
在java中,
MappedByteBuffer
是從堆中分配的(它是一個直接緩沖區)。
這沒有意義。 直接緩沖區不會從堆中分配,它們由mmap()
或平台API分配,作為新內存。 不在堆中。 MappedByteBuffer
是直接緩沖區是正確的。
所以當你從MappedByteBuffer中讀取時,是否意味着它需要從Java堆外部再添加一個額外的內存副本到java堆中?
是的,但不是出於上述原因。 原因是你必須調用MappedByteBuffer.get()/put(),
這本身就是一個額外的步驟。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.