2011-09-27 106 views
5

使用Java我想創建一個可以增長和增長的Map,並且可能大於可用內存的大小。現在顯然使用標準的POJO HashMap,我們將耗盡內存,並且JVM會崩潰。所以我正在考慮一個Map,如果它意識到內存不足,它可以將當前內容寫入磁盤。在Java中創建一個非常非常大的地圖

有沒有人執行過這樣的事情,或者知道現有的解決方案?

我想要做的是讀一個非常大的ASCII文件(比如說50Gb)一次一行。每行包含一個鍵和一個值。密鑰可以在文件中複製。然後,我會將每行存儲在一個Map中,這是一個值列表的鍵。這張地圖是一個只會發展壯大的對象。

任何建議非常感謝。

菲爾

更新:

感謝所有的意見和建議每一個人。由於我描述的問題,數據庫是正確的,可擴展的解決方案。我應該說,這是一個臨時地圖,需要在短時間內創建和使用,以幫助解析文件。在這種情況下,Michael的建議是「只存儲行號而不是實際值」是最合適的。將邁克爾的答案標記爲推薦的解決方案。

+3

使用內存數據庫(如HSQL)會不會更簡單? – mcfinnigan

+0

你映射了哪些鍵/值類型? –

+0

我並不熱衷於數據庫方法。它太重了。 – Phil

回答

12

我認爲你正在尋找一個數據庫。

+0

:)嗯,我確實考慮過一個數據庫,但我只是想要一個非常簡單的東西(比如一個Map)磁盤根據需要。問題是我們如何知道密鑰是否存在,所以也許它只能溢出地圖的「值」部分 – Phil

+0

可能的解決方案:使用地圖,但只存儲行號而不是實際值作爲值。您可以使用行號從文件中檢索實際值。 – michael667

+0

邁克爾 - 我確實想到了這一點,並使用RandomAccessFile閱讀器來閱讀。當時的痛苦是BufferedReader無法從文件中提供當前的讀取位置。丟失BufferedReader意味着失去了readLine的能力,它也與我的CSV解析混爲一談(我錯過了原來的問題,因爲它並不真正相關)。 – Phil

2

聽起來像將您的大文件轉儲到數據庫中。

那麼,我有這樣的情況。但是,在我的情況下,一切都在TXT文件格式,整個文件具有相同的格式化線。所以,我所做的只是將這些文件分成幾塊(可能是我的JVM可以處理的最大尺寸)。然後我逐個調用文件進行處理。

另一種方式,您可以直接將數據直接加載到數據庫中。

0

如果你只是想建立數據處理的地圖(而不是隨機訪問來響應請求),那麼MapReduce可能是你想要的,而不需要使用數據庫。

編輯:請注意,雖然許多MapReduce的介紹集中在運行多個節點的能力上,但您仍然應該避開將一個機器上的所有數據保存在內存中的需求。

0

你有多少內存?除非你有足夠的內存來保存內存中的大部分數據,否則它會很慢,否則它可能會失敗。一個大量分頁的程序可能會慢1000倍或更多。一些PC有16-24 GB,你可能會考慮獲得更多的內存。

假設有足夠的重複項,可以將大部分數據保留在內存中。我建議你使用你自己製作的一個基於字節的String類,因爲你有ASCII數據,並且將你的值存儲爲這些「String」類型中的另一個(帶有分隔符)。你可能發現你可以將工作數據集保存在內存中。

+0

如果你打算更輕量級的'String'路線,我會推薦['MutableString'](http://dsiutils.dsi.unimi.it/docs/it/unimi/dsi/lang/MutableString .html)類 - 它是爲此目的而設計的。 –

+0

MutableString使用char [],Even String可以將ascii字符串轉換爲使用byte []'-XX:+ UseCompressedStrings',這是新的JVM上的默認值。然而,它並不像你能做到的那樣高效。 –

2

說真的,建議選擇一個簡單的數據庫。這不是開銷—你不必使用JPA或者其他東西,只需要簡單的JDBC和原生SQL。例如,Derby或HSQL可以嵌入模式運行,不需要定義用戶,訪問權限,單獨啓動服務器。

「開銷」會在您深入研究哈希映射解決方案並且事實證明您需要進行另一次優化以避免OutOfMemoryException或文件不是50 GB,而是75 ......真的,不要去那裏。

3

NoSQL數據庫可能很容易設置,它更像一張地圖。 檢查現在來自Oracle的BerkeleyDB Java版本。 它有一個像接口的地圖,可以嵌入,所以不需要複雜的設置

+0

+1用於內存數據庫選項。 – FloppyDisk

0

我使用BerkleyDB這個,雖然它比一個地圖更復雜(雖然他們有一個Map包裝,我不建議任何東西,但簡單的應用程序)

http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html

它也可以在Maven的http://www.oracle.com/technetwork/database/berkeleydb/downloads/maven-087630.html

<dependencies> 
    <dependency> 
     <groupId>com.sleepycat</groupId> 
     <artifactId>je</artifactId> 
     <version>3.3.75</version> 
    </dependency> 
    </dependencies> 

    <repositories> 
    <repository> 
     <id>oracleReleases</id> 
     <name>Oracle Released Java Packages</name> 
     <url>http://download.oracle.com/maven</url> 
     <layout>default</layout> 
    </repository> 
    </repositories> 

它也有廠商鎖定的一個另一個缺點(比如,你是使用這個工具。儘管其他地圖封裝器可能還有其他數據庫)

所以,只需根據您的需要選擇。