繁体   English   中英

添加hashmap和arraylist时出现内存不足错误

[英]outofmemory error when adding hashmap and arraylist

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

我无法执行此操作,因为海量数据导致Java Heap空间错误。

但是我的应用程序需要哈希表列表(我不想增加堆空间)。

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);
 }

这听起来像是glib,但是您的问题是您的应用程序需要250万行的列表作为HashMaps。

这是荒谬,不合理和坦率的荒谬的要求; 我无法想象使用这种数据结构有什么好处。

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

您可以尝试使用byte []代替String对象: byte[] key = mappingKey.getBytes("UTF-8")

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

另外,每个String对象都包含对char数组的引用。 这意味着您在内存堆中有两个对象:String和char数组。 每个对象(甚至只是new Object() )的开销约为24个字节(取决于Java VM版本和选项)。

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

完全同意波希米亚的答案。

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

上述解决方案将严重依赖文件访问,因此请查看java.nio进行有效访问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM