Hadoop中的mapred.child.javaopts参数 - 读取序列化的HashMap

时间:2013-03-19 22:47:28

标签: hadoop mapreduce hdfs distributed-caching

我有一个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();
    }

1 个答案:

答案 0 :(得分:1)

当你使用哈希映射的序列化版本,并且文件的最终输出大小是1.5GB时,我猜你的JVM所需的内存量至少为1.5GB。 / p>

您应该可以使用一个小程序来测试它,以便加载到您的文件中(就像您已经拥有的那样),但是不断增加-Xmx值,直到您不再看到内存错误 - 这将是您的基线(您'在hadoop映射器中运行时,可能仍需要添加更多内容,因为它具有溢出排序等的缓冲区大小要求。

您是否也知道此哈希映射中有多少个bin和项目? HashMap的实现只是一个包含链接条目项的二进制数组,这些条目散列到该二进制数。 bin的数量也必须是2的幂,因此当您在地图中放置越来越多的项目时,当地图达到其阈值/载荷因子(0.75)时,实际后备阵列的内存要求会加倍。考虑到这一点,我想象你看到的问题是这样一个大型哈希映射(1.5GB序列化)在反序列化到内存时需要一个尽可能大的内存占用(