添加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);
}
# 1 楼答案
完全同意Bohemian的答案
为了帮助您,我建议您不要只读取一次文件并将所有内容都保存在内存中,而是只读取一次,维护一个“索引映射”(取决于您的需要)。然后,当你必须对你的文件进行研究时,你必须再次打开一个流,并使用你的“索引图”来优化搜索时间
上述解决方案将严重依赖于文件访问,因此请查看java.nio以获得高效访问
# 2 楼答案
您可以尝试使用字节[]而不是字符串对象:
byte[] key = mappingKey.getBytes("UTF-8")
每个字符串对象都包含一组UTF-16字符。在大多数情况下,它意味着每个符号有2个字节。UTF-8编码对ASCII使用一个字节,对许多欧洲语言使用两个字节
此外,每个字符串对象都包含对字符数组的引用。这意味着内存堆中有两个对象:字符串和字符数组。每个对象(即使只是
new Object()
)需要约24个字节(取决于Java VM版本和选项)因此,您可以轻松地将对象数减少2倍(一字节[]而不是成对字符串+字符[]),并且UTF-8符号的数组长度通常小于UTF-16字符的长度
# 3 楼答案
这听起来可能很油腔滑调,但您的问题是,您的应用程序需要一个包含250万行的列表作为哈希映射
这是一个荒谬的、不合理的、坦率地荒谬的要求;我无法想象使用这样的数据结构会有什么好处
将应用程序更改为不需要它