簡體   English   中英

Java - 使用多個線程讀取/寫入內存映射緩沖區(MappedByteBuffer)

[英]Java - Using multiple threads to read/write to memory mapped buffers (MappedByteBuffer)

我有一個應用程序,其中發生了大量的文件I / O(讀取和寫入)。 我知道使用多個線程來執行文件I / O並不是一個好的解決方案,因為它會降低性能(我無法控制所使用的磁盤類型)。 所以我最終為所有文件I / O專用了一個線程。 在我的情況下MappedByteBuffer可以用嗎? 我知道MappedByteBuffer是一個由操作系統映射到文件的內存區域,我可以利用多個線程有效地對不同的內存映射緩沖區進行I / O操作嗎? 當多個線程將不同的文件映射到不同的內存緩沖區時,磁頭搜索時間是否仍然重要? 在這種情況下是否保證一致性? 是否有針對此類案例的基准測試結果?提前感謝大家。

在我的情況下MappedByteBuffer可以用嗎?

與ByteBuffer相比,參考JavaDoc MappedByteBuffer應該沒有性能優勢。 在運行時,您甚至可能會遇到一些意外的更改

映射字節緩沖區的內容可以隨時改變,例如,如果該程序或其他程序改變了映射文件的相應區域的內容。


我知道MappedByteBuffer是一個由操作系統映射到文件的內存區域,我可以利用多個線程有效地對不同的內存映射緩沖區進行I / O操作嗎?

除了您比操作系統或VM更了解如何有效地讀取和寫入數據之外,情況並非如此。


當多個線程將不同的文件映射到不同的內存緩沖區時,磁頭搜索時間是否仍然重要?

頭仍然要尋求其立場。 除非你有不同的磁盤並且只做磁盤IO,否則擁有多個線程是沒用的。 如果您有一些冗余讀取數據多線程應該是有用的,因為您的操作系統將緩存“熱”數據。


在這種情況下是否保證一致性?

不是很確定,你的意思,但你必須確保以某種方式同步訪問你的ByteBuffer,因為它不是線程安全的數據結構。


是否有針對此類案例的基准測試結果?

去年我做了一些基准測試,使用多個緩沖區。 簡而言之,它實際上取決於用例,操作系統和硬件。 根據這是多么重要,我建議你做自己的基准測試。 我記得的唯一不變的是你獲得了最佳性能寫入你的磁盤段大小的數據塊......這在某種程度上是顯而易見的;-)

只要你沒有嘗試在給定時間有多個線程寫入同一個文件,從不同的線程執行文件I / O就沒有問題。 使用NIO,FileSystem實現比您希望管理磁盤寫入和資源更好。 默認情況下,Java中的磁盤寫入是緩沖和異步的,因此不需要像使單個線程執行所有I / O並寫入內存緩沖區那樣進行復雜的操作 - 這幾乎就是OutputStreams寫入磁盤的內容,但是本機JVM將比您更有效地完成它。

實際上,文件I / O操作可以從多線程中獲益。 當其他線程正在讀取時,不同的線程可以處理讀取信息,並且有時甚至可以更快地並行地讀取或寫入一些並行的文件。

如果您建議您要將同一文件的不同區域映射到不同的MappedByteBuffers,並希望比較將文件寫入單線程,阻塞,無緩沖寫入同一文件,我很確定你從性能角度來看,我們會對結果非常滿意。

您應該記住,在寫入MemoryMappedBuffers時,當您請求執行寫操作時,您不一定要寫入磁盤。 操作系統負責決定哪個MemoryMappedBuffers對應RAM以及何時將RAM寫回磁盤; 通常這意味着在寫入時,該文件或文件的一部分保存在RAM中,並且該文件由操作系統自行決定寫回磁盤,這可能意味着它保留在內存中,直到看起來您已完成寫入它,然后移動到磁盤,或者它保存在RAM中,直到它占用的RAM需要其他東西,除非你force()它寫入磁盤。

我認為,從性能的角度來看,它很大程度上取決於你的目標是什么:你是否希望你的算法能夠更快地完成寫入,在這種情況下,內存映射區域可能是一個不錯的選擇,因為算法可以完成在文件寫入磁盤之前,或者您希望將文件更快地復制到磁盤上,在這種情況下很難說:如果您能夠將文件拆分成可以有效寫入磁盤的漂亮大塊,並且如果操作系統能夠識別您完成區域的時間,並且在此過程中僅將每個區域寫回磁盤一次,則可能更有效。

另一方面,如果您當前的實現非常有效地寫入磁盤,即如果您成功地有效地安排了對文件的寫入,那么幾乎沒有必要(如果使用硬盤),並且寫入被適當地緩沖,這樣你就不會強迫操作系統將文件的一小部分一直寫入磁盤,然后再允許它擁有文件的下一位,或者隨機寫入字節(即使是固態驅動器也不喜歡,因為它們必須寫一個特定大小的區域,並且不能單獨寫單個字節),那么你的當前策略完全有可能更快地將文件寫入磁盤 - 假設盡可能快地將文件放到物理磁盤上是目標。

如果您想知道有多少改進空間,您可以將速度與系統硬盤性能測試的速度進行比較,這應該能夠將您的吞吐量限制與磁盤進行對比; 如果這比你當前的實現要快得多,那么你的寫作策略還有改進的余地,或者它是在生成數據而不是編寫數據,而是花費時間。

要測試后者,您可以嘗試讓算法寫入不是內存映射的ByteBuffers; 如果沒有文件I / O,您可以獨立於磁盤對算法的速度進行基准測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM