Hadoop 通过DistributedCache读取本地文件时发生OutofMemoryError

Hadoop 通过DistributedCache读取本地文件时发生OutofMemoryError,hadoop,mapreduce,out-of-memory,Hadoop,Mapreduce,Out Of Memory,2012年11月21日更新: 通过将属性mapred.child.java.opts设置为-Xmx512m,问题得以解决。在此之前,我在core-site.xml中将HADOOP_HEAPSIZE设置为2000,但这没有帮助。我仍然不明白为什么这个程序在本地运行,但它不是分布式的。谢谢你的回答 我正在使用Hadoop 1.0.3。集群由三台机器组成,它们都运行Ubuntu Linux 12.04 LTS。其中两台机器有12 GB的RAM,第三台机器有4 GB。我正在通过DistributedCa

2012年11月21日更新:


通过将属性mapred.child.java.opts设置为-Xmx512m,问题得以解决。在此之前,我在core-site.xml中将HADOOP_HEAPSIZE设置为2000,但这没有帮助。我仍然不明白为什么这个程序在本地运行,但它不是分布式的。谢谢你的回答

我正在使用Hadoop 1.0.3。集群由三台机器组成,它们都运行Ubuntu Linux 12.04 LTS。其中两台机器有12 GB的RAM,第三台机器有4 GB。我正在通过DistributedCache读取一个大约40 MB的本地文件。我的程序在本地环境(本地/独立模式)中运行良好。然而,当我在Hadoop集群(完全分布式模式)中执行它时,我得到了一个“OutOfMemoryError:Java堆空间”,它具有相同的40MB文件。我不明白为什么会发生这种情况,因为文件没有那么大。代码如下:

    public static class MapClass extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> {
    // ...
    private HashMap<String, String> urlTrad = new HashMap<String, String>();
    // ...
    @Override
    public void configure(JobConf job) {
        Path[] urlsFiles = new Path[0];
        BufferedReader fis;

        try {
            urlsFiles = DistributedCache.getLocalCacheFiles(job);
            fis = new BufferedReader(new FileReader(
                    urlsFiles[0].toString()));
            String pattern;
            while ((pattern = fis.readLine()) != null) {
                String[] parts = pattern.split("\t");
                urlTrad.put(parts[0], parts[1]);
            }
            fis.close();

        } catch (IOException ioe) {
            System.err
                    .println("Caught exception while parsing the cached file '"
                    + urlsFiles[0]
                    + "' : "
                    + StringUtils.stringifyException(ioe));
        }
    }
    // ...
公共静态类MapClass扩展MapReduceBase实现Mapper{
// ...
私有HashMap urltra=新HashMap();
// ...
@凌驾
公共无效配置(JobConf作业){
路径[]urlsFiles=新路径[0];
缓冲式读写器;
试一试{
urlsFiles=DistributedCache.getLocalCacheFiles(作业);
fis=新的BufferedReader(新的文件读取器(
urlsFiles[0].toString());
字符串模式;
而((pattern=fis.readLine())!=null){
String[]parts=pattern.split(“\t”);
urlTrad.put(第[0]部分、第[1]部分);
}
fis.close();
}捕获(ioe异常ioe){
System.err
.println(“分析缓存文件时捕获异常”)
+URL文件[0]
+ "' : "
+StringUtils.stringifyException(ioe));
}
}
// ...

感谢您的帮助。

通过将属性mapred.child.java.opts设置为-Xmx512m解决了问题。在此之前,我在core-site.xml中将HADOOP_HEAPSIZE设置为2000,但这没有帮助。我仍然不明白为什么程序在本地工作,但它不是分布式的。

尝试关闭文件阅读器?@ChrisGerken
FileReader
通过对其包装的读取器调用close来隐式关闭。我怀疑那里有另一个内存泄漏。@ThomasJungblut我知道,但当我的一个假设明显错误时,我想返回并再次测试每一个。您是否尝试使用jmap或visualvm运行代码以获得一些见解?有多少插槽(map/reduce)你有内存吗?你使用的内存配置是什么?听起来你没有太多的内存。