我正在尝试在映射器中读取多行。为此,我开始使用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映射器。为什么我收到此错误?请帮我解决此错误。
提前谢谢。
为什么我会收到此错误?
通常,OOME 最可能的解释是内存不足,因为
- 您的代码存在内存泄漏,或者 你
- 没有足够的内存来做你想做的事情/你试图做它的方式。
(有了 OOME 的这种特殊"风格",你还没有完全耗尽内存。 但是,您很可能即将用完,这导致 GC CPU 利用率飙升,超过了"GC 开销"阈值。 此细节不会改变您应该尝试解决问题的方式。
在您的情况下,当您将输入从文件加载到地图(或地图集合)时,似乎发生了错误。 因此,推论是你告诉Hadoop加载的数据比一次内存中容纳的数据多。
请帮我解决此错误。
解决 方案:
- 减小输入文件大小;例如,将问题分解为更小的问题
- 增加受影响 JVM 的内存大小(特别是 Java 堆大小)。
- 更改您的应用程序,以便作业从文件(或 HFS)本身流式传输数据...而不是将 CSV 加载到地图中。
如果您需要更具体的答案,则需要提供更多详细信息。
添加到 Stephen C 答案,其中列出了可能的解决方案
从预言机文档链接,
线程 thread_name 中的异常:java.lang.OutOfMemory错误:超出 GC 开销限制
原因:详细信息消息"超出 GC 开销限制"表示垃圾回收器一直在运行,Java 程序的进度非常慢。在垃圾回收之后,如果 Java 进程花费了大约 98% 的时间进行垃圾回收,并且它恢复的堆不到 2%,并且到目前为止已经连续执行了 5 次(编译时常量)垃圾回收,则会抛出 java.lang.OutOfMemoryError。
通常会引发此异常,因为实时数据量几乎无法放入 Java 堆,几乎没有可用空间用于新分配。
要执行的操作: 增加堆大小。java.lang.OutOfMemoryError 超出 GC 开销限制的异常可以使用命令行标志 -XX:-UseGCOverheadLimit 关闭。
请查看此 SE 问题以更好地处理此错误:
java.lang.OutOfMemoryError: 超出 GC 开销限制