我有一个1.5 GB的文件,其中包含一个序列化的HashMap。
我在Mapper类中有一个setup()方法,我将其读入HashMap变量。
看起来它可以转到read方法,但会立即为任务抛出java堆空间错误。
我阅读了许多讨论,我们可能需要设置mapred.child.opts参数,我在主程序代码中执行此操作。
我正在使用: conf.set(“mapred.child.java.opts。”,“ - Xmx1024M”);
我甚至试图增加这个数字。为什么在尝试将序列化文件读入HashMap变量时仍然会抛出同样的错误?
以下是我的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();
}
答案 0 :(得分:1)
当你使用哈希映射的序列化版本,并且文件的最终输出大小是1.5GB时,我猜你的JVM所需的内存量至少为1.5GB。 / p>
您应该可以使用一个小程序来测试它,以便加载到您的文件中(就像您已经拥有的那样),但是不断增加-Xmx值,直到您不再看到内存错误 - 这将是您的基线(您'在hadoop映射器中运行时,可能仍需要添加更多内容,因为它具有溢出排序等的缓冲区大小要求。
您是否也知道此哈希映射中有多少个bin和项目? HashMap的实现只是一个包含链接条目项的二进制数组,这些条目散列到该二进制数。 bin的数量也必须是2的幂,因此当您在地图中放置越来越多的项目时,当地图达到其阈值/载荷因子(0.75)时,实际后备阵列的内存要求会加倍。考虑到这一点,我想象你看到的问题是这样一个大型哈希映射(1.5GB序列化)在反序列化到内存时需要一个尽可能大的内存占用(
)