Hadoop 故障:java.lang.OutOfMemoryError: Java heap space

一个作业运行时,在maptask阶段出现了如下错误:
FATAL org.apache.hadoop.mapred.Child: Error running child : java.lang.OutOfMemoryError: Java heap space
        at org.apache.hadoop.io.Text.setCapacity(Text.java:240)
        at org.apache.hadoop.io.Text.append(Text.java:216)
        at org.apache.hadoop.util.LineReader.readLine(LineReader.java:159)
        at org.apache.hadoop.mapreduce.lib.input.LineRecordReader.nextKeyValue(LineRecordReader.java:97)
        at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.nextKeyValue(MapTask.java:532)
        at org.apache.hadoop.mapreduce.MapContext.nextKeyValue(MapContext.java:67)
        at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:143)
        at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370)
        at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:416)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)
        at org.apache.hadoop.mapred.Child.main(Child.java:249)
根据错误信息初步判断是JVM堆内存不够用导致,有可能是单条数据过大,或JVM内存过小导致,首先验证了该错误并非数据导致,方法是把导致问题的那行数据导出来,单独运行了MR是没有问题的,检查了MR没有死循环分配内存的问题,那基本可以断定确实是JVM的内存太小了,JVM的默认内存分配有两种可能 1)、系统JVM默认分配,大小为物理内存的1/4 2)、在任务脚本执行时指定
map的执行脚本会被hadoop封装在taskjvm.sh中,文本文件可以直接查看

exec setsid '/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/bin/java' '-Djava.library.path=/opt/hadoop104/libexec/../lib    /native/Linux-amd64-64:/data/tmp/mapred/local/taskTracker/hc/jobcache/job_201310281456_0718/attempt_201310281456_0718_m_0000    00_0/work' '-Xmx200m' '-Djava.net.preferIPv4Stack=true' .....
分配了200m,由于集群中没有修改mapred.child.java.opts这个参数,在1.0.4版本中该值为 -Xmx200m,io.sort.mb默认为100m,那么只剩100m供任务使用了,程序中的对象实例会用一部分,运行时临时分配的buffer会用一部分,例如LineRecordReader分配的读入缓冲区。这里只要修改mapred.child.java.opts这个参数就可以了
mapred-site.xml 添加:

     <property>
              <name>mapred.child.java.opts</name>
              <value>-Xmx1024m</value>
     </property>
这种办法并不通用,因为很多情况下内存过载是由于代码造成的,那种情况下就要具体分析了。
对于JVM内存的查看可以使用jconsole,这是个图形界面,能够远程连接JVM进程,分析JVM性能时可以使用这个工具
1、启动JVM时添加如下参数

java -Djava.rmi.server.hostname=192.168.2.38 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false test

2、在客户端连接上面端口




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当你在使用Flink时遇到"java.lang.OutOfMemoryError: Java heap space"错误时,这意味着Java堆内存不足以处理当前的任务或数据量。这通常是由于以下几个原因导致的: 1. 数据量过大:如果你的任务处理的数据量非常大,超过了Java堆内存的限制,就会导致内存溢出错误。这可能是因为你的输入数据集太大,或者你的计算逻辑导致了大量的中间数据产生。 2. 内存设置不合理:Flink的任务执行需要合理的内存配置。如果你的任务需要更多的内存来处理数据,你可以通过调整Flink的任务管理器和执行器的内存设置来解决问题。 解决这个问题的方法有以下几种: 1. 增加Java堆内存:你可以通过增加Java堆内存的大小来解决这个问题。可以通过修改Flink的启动脚本或配置文件中的相关参数来实现。例如,可以通过设置`-Xmx`参数来增加最大堆内存大小。 2. 优化任务逻辑:检查你的任务逻辑是否存在内存泄漏或者不必要的数据复制等问题。尽量减少中间数据的产生和复制,可以使用Flink提供的一些优化技术,如状态后端选择、数据本地性等。 3. 增加并行度:如果你的任务可以进行并行处理,可以尝试增加任务的并行度。这样可以将数据分散到更多的任务实例中,减少每个任务实例的内存压力。 4. 使用外部存储:如果你的数据量非常大,无法在有限的内存中处理,可以考虑使用外部存储来存储和处理数据。Flink提供了与各种外部存储系统(如Hadoop HDFS、Amazon S3等)的集成,可以将数据存储在外部存储中,并通过Flink进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值