有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

添加hashmap和arraylist时发生java outofmemory错误

我们在csv文件中有大量数据。它有250万行,每行有10个字段,我们正在尝试为每行准备hashmap,然后将该hashmap添加到arraylist

我无法做到这一点,因为巨大的数据量会导致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);
 }

共 (3) 个答案

  1. # 1 楼答案

    完全同意Bohemian的答案

    为了帮助您,我建议您不要只读取一次文件并将所有内容都保存在内存中,而是只读取一次,维护一个“索引映射”(取决于您的需要)。然后,当你必须对你的文件进行研究时,你必须再次打开一个流,并使用你的“索引图”来优化搜索时间

    上述解决方案将严重依赖于文件访问,因此请查看java.nio以获得高效访问

  2. # 2 楼答案

    您可以尝试使用字节[]而不是字符串对象: byte[] key = mappingKey.getBytes("UTF-8")

    每个字符串对象都包含一组UTF-16字符。在大多数情况下,它意味着每个符号有2个字节。UTF-8编码对ASCII使用一个字节,对许多欧洲语言使用两个字节

    此外,每个字符串对象都包含对字符数组的引用。这意味着内存堆中有两个对象:字符串和字符数组。每个对象(即使只是new Object())需要约24个字节(取决于Java VM版本和选项)

    因此,您可以轻松地将对象数减少2倍(一字节[]而不是成对字符串+字符[]),并且UTF-8符号的数组长度通常小于UTF-16字符的长度

  3. # 3 楼答案

    这听起来可能很油腔滑调,但您的问题是,您的应用程序需要一个包含250万行的列表作为哈希映射

    这是一个荒谬的、不合理的、坦率地荒谬的要求;我无法想象使用这样的数据结构会有什么好处

    将应用程序更改为不需要它