2015-10-29 63 views
1

我正在從具有大量數據的IO中讀取數據,並且需要將數據存儲在Map或屬性文件中的鍵值對中,然後我纔可以使用該數據生成報告。但是,當我將這些龐大的數據存儲在Map或Properties文件中時,堆內存異常即將到來。相反,如果我使用SQLLite,則需要花費非常多的時間來檢索它。有沒有什麼不同的方式來實現這一點。請建議。如何避免Java中的Java堆空間異常

+0

[Java堆內存錯誤(可能的重複http://stackoverflow.com/questions/3443937/java-heap-memory-error) – Reinard

+0

對於這種情況,如果我們增加堆,問題仍然存在,請不要增加堆以任何方式給我建議 –

+0

你可以做的是讀取數據塊的字節,將其存儲在地圖上,然後進一步處理。從您的問題中我可以看到,您正在讀取大量數據並將其存儲在地圖或屬性文件中,因爲您正在處理大量數據並充分利用JVM。可能這可能是你獲得堆空間異常的原因。試一試大塊頭 –

回答

0

增加堆大小是一個選項,但使用內存映射文件java.You可以參考this

+0

在我們的例子中,我們正在讀取來自配置單元的數據,並試圖將數據放入地圖或根據一些匹配的條件。讀取文件後,我們可以使用RandomAccessFile來提供先生。 –

2

Java堆空間要點

  1. 的Java存儲堆外的數據替代堆內存是由操作系統分配給JVM的內存的一部分。

  2. 每當我們創建對象時,它們都是在Java中的堆內部創建的。

  3. Java堆空間被分爲三個區域或一代,爲了垃圾收集而被稱爲新一代,舊的或老生代或彼爾姆空間。永久生成是在熱點JVM中在完整gc期間收集的垃圾。

  4. 通過使用JVM命令行選項-Xms,-Xmx和-Xmn,可以增加或更改Java堆空間的大小。在指定大小以指示Mega或Gig之後,不要忘記添加單詞「M」或「G」。 例如,您可以通過執行以下命令java -Xmx256m javaClassName(您的程序類名稱)將java堆大小設置爲258MB。

  5. 您可以使用JConsole或Runtime.maxMemory(),Runtime.totalMemory(),Runtime.freeMemory()查詢Java中編程的堆大小。

  6. 您可以使用命令「jmap」在Java中進行堆轉儲,並使用「jhat」來分析堆轉儲。

  7. Java堆空間不同於用於存儲調用層次結構和局部變量的堆棧。

  8. Java垃圾回收器負責從死對象中回收內存並返回到Java堆空間。

  9. 當你得到java.lang.OutOfMemoryError時,不要驚慌,有時它只是增加堆大小的問題,但如果它是經常性的,那麼在Java中尋找內存泄漏。

  10. 使用事件探查器和堆轉儲分析器工具來了解Java堆空間以及爲每個對象分配了多少內存。

參考鏈接查看更多細節:

https://docs.oracle.com/cd/E19159-01/819-3681/abeii/index.html

https://docs.oracle.com/cd/E40520_01/integrator.311/integratoretl_users/src/ti_troubleshoot_memory_errors.html

2

你需要做的的需要爲您的地圖存儲一個粗略的估計。多少個鍵和值?鍵和值有多大?例如,如果鍵長,並且值的字符串平均長度爲40個字符,則20億個鍵值對的絕對最小值爲(40 + 8)* 2E9 - 大約100 GB。當然,真正的要求大於最小估計值 - 根據鍵和值的性質,要大兩倍。

如果估計的內存超出合理範圍(100 GB超出了合理範圍,除非您有很多錢),則需要找出一種劃分處理的方法。你需要讀入大量的數據,然後在其上運行一些算法以將其縮小到一定的尺寸。然後逐個處理所有其他塊,確保在處理新塊時不要將舊塊留在周圍。最後,查看所有塊的結果並計算最終結果。爲了更好地描述這種方法,請查看「map-reduce」。

如果估計的內存量有些合理(比如說8 GB - 而且有16 GB的機器) - 使用64位JVM,設置最大堆內存使用-Xmx開關,確保使用最有效的數據結構,如特羅韋地圖。

祝你好運!

相關問題