2014-12-29 42 views
1

我們在csv文件中有大量數據。它有250萬行,每行有10個字段,我們正在嘗試爲每行準備hashmaps,然後將該hashmap添加到arraylist。添加hashmap和arraylist時outofmemory錯誤

由於大量數據拋出內存Java堆空間錯誤,我無法做到這一點。

但我的應用程序需要hashmap列表(我不想增加heapspace)。

reader = new CSVReader(new FileReader(dataFile),','); 
     Map<String, String> feedMap = null; 
     String[] firstLine; 
     String[] nextLine; 
     String mappingKey = null; 
     String mappingValue = null; 
     //Read one line at a time 
     firstLine = reader.readNext(); 
     while ((nextLine = reader.readNext()) != null){ 
      int i = 0; 
      feedMap = new HashMap<String, String>(); 
      for(String token : nextLine){ 
       mappingKey = xmlNodeMap.get(firstLine[i]);      
       if (mappingKey != null) { 
        mappingValue = token.trim().length() > 0 ? token : Constants.NO_VALUE; 
        feedMap.put(mappingKey, mappingValue); 
       } 
       i++; 
     }     
     listOfMaps.add(feedMap); 
} 
+4

那麼,要保存大量的數據在內存中,你需要大量的內存。所以它要麼通過記錄來處理數據記錄,要麼將其全部保存在內存中並增加堆。那裏也沒有免費的午餐。 –

回答

0

您可以嘗試使用字節[]而不是String對象: byte[] key = mappingKey.getBytes("UTF-8")

每個字符串對象包含設置UTF-16字符的。這意味着在大多數情況下每個符號有2個字節。 UTF-8編碼對於ASCII使用一個字節,對於許多歐洲語言使用兩個字節。

另外每個String對象都包含對char數組的引用。這意味着你在內存堆中有兩個對象:String和char數組。每個對象(即使只是new Object())的成本約爲24字節(它取決於版本Java VM和選項)。

因此,您可以輕鬆地減少對象的數量(一個字節[]而不是對String + char []),並且UTF-8符號的數組長度通常小於UTF-16字符的長度。

2

這可能聽起來不錯,但問題是您的應用程序需要一個250萬行的列表作爲HashMaps。

這是荒謬的,不合理的和坦率的荒謬的要求;我無法想象使用這種數據結構會有什麼好處。

將應用程序更改爲不需要它。

+0

那麼,finnaly我們根據文件總大小將文件分割爲1,00,000行,然後我們添加到映射每個單個文件,並使用文件列表處理數據庫。 –

0

完全同意Bohemian的答案。

爲了幫助您,我建議您不要只讀一次文件並將所有內容都保存在內存中,而應該只讀一次,並維護一個「索引圖」(根據您的需要)。然後,當你必須對你的文件進行研究時,你將不得不再次打開一個流,並使用你的「索引圖」來優化搜索時間。

上述解決方案將嚴重依賴文件訪問,因此請高效訪問java.nio