使用NLineInputFormat用法超出了GC开销限制

时间:2016-02-21 04:49:30

标签: java hadoop mapreduce garbage-collection hadoop2

我正在尝试在mapper中读取多行。为此,我开始使用NLineInputFormat类。使用它时,我收到GC限制错误。作为参考,错误代码是:

16/02/21 01:37:13 INFO mapreduce.Job:  map 0% reduce 0%
16/02/21 01:37:38 WARN mapred.LocalJobRunner: job_local726191039_0001
java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1019)
at java.util.concurrent.ConcurrentHashMap.putAll(ConcurrentHashMap.java:1084)
at java.util.concurrent.ConcurrentHashMap.<init>(ConcurrentHashMap.java:852)
at org.apache.hadoop.conf.Configuration.<init>(Configuration.java:713)
at org.apache.hadoop.mapred.JobConf.<init>(JobConf.java:442)
at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.<init>(LocalJobRunner.java:217)
at org.apache.hadoop.mapred.LocalJobRunner$Job.getMapTaskRunnables(LocalJobRunner.java:272)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:517)
16/02/21 01:37:39 INFO mapreduce.Job: Job job_local726191039_0001 failed with state FAILED due to: NA

如需参考,请参阅下面的代码段。

public class JobLauncher {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "TestDemo");
        job.setJarByClass(JobLauncher.class);

        job.setMapperClass(CSVMapper.class);
        job.setMapOutputKeyClass(NullWritable.class);
        job.setMapOutputValueClass(NullWritable.class);

        conf.setInt(NLineInputFormat.LINES_PER_MAP, 3);
        job.setInputFormatClass(NLineInputFormat.class);
        NLineInputFormat.addInputPath(job, new Path(args[0]));

        job.setNumReduceTasks(0);
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
   }
}

我只有简单的CSVMapper映射器。为什么我收到此错误?请帮我解决这个错误。

提前致谢。

2 个答案:

答案 0 :(得分:1)

  

为什么我收到此错误?

一般来说,对OOME最可能的解释是你的内存不足,因为

  • 您的代码有内存泄漏,或
  • 你没有足够的内存来处理你想要做的事情/ 你想要做的事情

(使用OOME的这种特殊情况&#34;你还没有完全耗尽内存。但是,你很可能接近耗尽,并且这导致GC CPU利用率飙升,超过了GC的开销阈值。这个细节并没有改变你应该尝试解决问题的方式。)

在您的情况下,当您将文件中的输入加载到地图(或地图集合)时,看起来似乎发生了错误。因此推断你已经告诉Hadoop加载的数据多于一次适合内存的数据。

  

请帮我解决此错误。

解决方案:

  • 减少输入文件大小;例如将问题分解为更小的问题
  • 增加受影响的JVM的内存大小(特别是Java堆大小)。
  • 更改您的应用程序,以便作业自己从文件(或从HFS)流式传输数据...而不是将CSV加载到地图中。

如果您需要更具体的答案,则需要提供更多详细信息。

答案 1 :(得分:0)

添加 Stephen C 回答,其中列出了可能的解决方案

来自oracle文档link

thread thread_name中的异常:java.lang.OutOfMemoryError:超出GC开销限制

  

原因:详细消息“超出GC开销限制”表示垃圾收集器一直在运行,Java程序进展非常缓慢。在垃圾收集之后,如果Java进程花费超过大约98%的时间进行垃圾收集,并且它正在恢复少于2%的堆并且到目前为止已经执行了最后5个(编译时常量)连续垃圾集合,然后抛出java.lang.OutOfMemoryError。

     

通常会抛出此异常,因为实时数据量几乎不适合Java堆,而新分配的可用空间很小。

     

操作:增加堆大小。可以使用命令行标志-XX:-UseGCOverheadLimit关闭超出GC Overhead限制的java.lang.OutOfMemoryError异常。

请查看此SE问题,以便更好地处理此错误:

java.lang.OutOfMemoryError: GC overhead limit exceeded