我有一个1.5gb的文件,其中包含一个序列化的hashmap。
我在mapper类中有一个setup()方法,我将它读入hashmap变量。
它看起来可以转到read方法,但是会立即抛出任务的java堆空间错误。
我阅读了许多关于可能需要设置mapred.child.opts参数的讨论,我正在主程序代码中这样做。
我使用的是:conf.set(“mapred.child.java.opts.”,“-xmx1024m”);
我甚至试着增加人数。为什么它在尝试将序列化文件读入hashmap变量时仍然抛出相同的错误?
下面是my setup()方法中的代码:
try {
test="hello";
Path pt=new Path("hdfs://localhost:9000/user/watsonuser/topic_dump.tsv");
FileSystem fs = FileSystem.get(new Configuration());
}catch(Exception e) {System.out.println("Exception while reading the nameMap
file."); e.printStackTrace();}
InputStream is = fs.open(pt);
ObjectInputStream s = new ObjectInputStream(is);
nameMap = (HashMap<String, String>) s.readObject();
s.close();
}catch(Exception e) {
System.out.println("Exception while reading the nameMap file.");
e.printStackTrace();
}
1条答案
按热度按时间fnatzsnv1#
由于您使用的是哈希Map的序列化版本,并且文件的最终输出大小是1.5gb,因此我猜您的jvm需要的内存量至少是1.5gb。
您应该能够用一个小程序来测试这个问题,然后加载到您的文件中(正如您已经拥有的那样),但是要不断增加-xmx值,直到您不再看到内存错误为止-这将是您的基线(在hadoopMap器中运行时,您可能还需要添加一些内容,因为它需要缓冲区大小来进行排序等)。
你还知道这个散列图中表示了多少个箱子和项目吗?hashmap的实现只是一个包含链接条目项的bin数组,这些条目项散列到该bin编号。存储箱的数量也必须是2的幂,因此当您在Map中放置越来越多的项目时,当Map达到其阈值/负载系数(0.75)时,实际备份数组的内存需求将翻倍。考虑到这一点,我认为您看到的问题是,这样一个大的哈希Map(1.5gb序列化)在反序列化到内存中时需要同样大的内存占用(如果不是更大的话)