1

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

1 回答 1

1

由于您使用的是哈希映射的序列化版本,并且文件的最终输出大小为 1.5GB,我猜测您的 JVM 将需要的内存量至少为 1.5GB。

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

您是否还知道此哈希图中表示了多少箱和项目?HashMap 的实现只是一个带有链接条目项的 bin 数组,这些条目项哈希到该 bin 编号。bin 的数量也必须是 2 的幂,因此当您在地图中放置越来越多的项目时,当地图达到其阈值/负载因子 (0.75) 时,实际后备数组的内存需求会翻倍。考虑到这一点,我想您看到的问题是,当反序列化到内存时,如此大的哈希映射(1.5GB 序列化)将需要同样大的内存占用,如果不是更大的话

于 2013-03-20T10:41:08.610 回答