2014-09-04 79 views
1

我們的Java程序具有樹形結構大對象,ArrayList和MultiMaps。Java大型對象存儲 - 協議緩衝區,MemoryMappedFiles

我遇到的問題是,我們已經分配了3GB的堆內存,但它仍然沒有空間。

我想知道如果在這裏任何人都可以提出一個方法來存儲外堆這些對象和讀取數據的塊放回每個處理的呼叫需要的基礎上java程序。我有興趣將它們存儲在文件中而不是其他原因的數據庫中。

我碰到了「內存映射文件」,有些人建議「協議緩衝區」上一個相關的問題,這些都是目前外星人的概念給我,想知道如果有一個簡單的方法。我也無法在這兩個概念上找到好的例子。

真的很感謝你對此的幫助。

性能是非常重要的考慮因素,我知道JVM堆分配,但我不尋找增加的JVM堆大小。

+0

聽起來像一個* XY問題*。認爲我錯了?提供有關「大型對象」的詳細信息以及如何使用它們。告訴我們爲什麼你想探索像mem映射文件這樣的奇特解決方案。 – Andreas 2014-09-04 19:34:15

+0

我已經把數據放在一個帶有Java的內存映射文件中,但缺點是那裏存儲的數據不是Java對象 - 它看起來像一個大字節數組。 – antlersoft 2014-09-04 19:35:08

+0

@Andreas,謝謝你的迴應。我們將後端表數據讀入Java,並基於某些邏輯將此數據轉換爲Java數據結構 - 樹數據結構,對象ArrayList和MultiMaps。 我有Java邏輯從這些對象和數據結構讀取並根據它們的輸入處理用戶請求。 如果仍然不清楚,我真的很抱歉。希望我能提供更多細節。 而我不得不尋求奇特的解決方案。我會採納你的任何建議。 – 2014-09-04 19:45:00

回答

1

您可能會考慮將數據存儲在Chronicle Map之類的東西中。這使用堆內存,並可以存儲和訪問,而不會產生任何垃圾。這可以讓你減少堆的大小,但你仍然需要購買一塊合理的內存。我建議你考慮至少有32 GB的內存,不管你是在堆上使用還是在堆外使用大型數據集。

沒有理由我必須去異國情調的解決方案

在這種情況下,堅持一個上堆的解決方案。你可以購買大約200美元的16 GB內存。

我不是在尋找增加JVM堆大小。

問問你自己願意投入多少時間/金錢以避免增加堆。你當然可以做到這一點,但爲了節省4 GB,我不會在這一天度過一天。節省40 GB或400 GB或4 TB是另一回事。

+0

嗨,彼得, 非常感謝您的回覆。 我會檢查你的建議。 而且,這不是我個人的工作,我可以輕鬆獲得16GB的RAM。這是我的辦公室項目,想要獲得這麼多的記憶並不容易,相信我。 – 2014-09-04 20:32:56

+2

@bluzeee是的,有些地方會很樂意浪費大量時間/金錢以避免在硬件上花費金錢。 – 2014-09-04 20:49:50

0

您可能能夠使用Guava中的不可變集合,它們通常會減少內存消耗。

您可以使用String.intern如果字符串把你的記憶中相當一部分。

您可以保存使用trove4j如果你有很多盒裝原語很多。

你可以做一些小技巧,例如使用更小的數據類型,等等....

但你真的應該浪費具有儘可能多的RAM作爲智能手機電腦的時間在你的辦公室獲取更多的內存!

+0

感謝您的回覆。 我檢查過Trove和HPPC,但我有對象而不是原始圖片。我也檢查了巨大的集合,並根據我檢查了什麼,我需要自定義接口,但我使用了ArrayList和收集對象(不是單獨的字符串)的映射,它們是內存的主要消費者。 我終於落戶Fastutil,但沒有看到任何內存節省,不知道如果我做錯了什麼。我必須進一步檢查。 – 2014-09-07 03:15:49

1

Protocol Buffers的不內存映射文件很好地工作,因爲該文件中包含的編碼數據,必須首先被解碼,然後才能使用它。該解碼步驟會生成堆對象。如果將文件拆分成許多小型消息,並在需要時按需解碼,但可以立即丟棄解碼版本,則可以將Protobufs與內存映射文件一起使用。但是,如果您不小心,可能會浪費大量時間重複解碼相同的數據。

Cap'n Proto是一種較新的格式,它與協議緩衝區非常相似,但明確設計用於處理內存映射文件。磁盤格式的設計使得它可以在沒有解碼步驟的情況下就地使用。我們正在研製一種Java version,該產品應在幾周內準備好用於生產。

(披露:我是頭兒原的創造者,也是以前Protocol Buffers的在谷歌的維護者)

+0

感謝您的回覆。 – 2014-09-07 03:09:26