DataX java.lang.OutOfMemoryError: GC overhead limit exceeded 一次OOM问题排查

在一次使用datax从gbase读数据写入sqlserver,长时间日志显示task的各项指标都是0,报“java.lang.OutOfMemoryError: GC overhead limit exceeded”。调整了reader的fetchSize和writer的batchSize,比较极端降到了1依然报错。

datax报错信息

开始跟着网上的资料排查问题

首先在启动脚本中添加了-XX:-UseGCOverheadLimit命令。

python datax.py --jvm="-Xms3G -Xmx3G -XX:-UseGCOverheadLimit" ../job/oom.json

报错信息变成了

“java.lang.OutOfMemoryError: Java heap space”

然后尝试增加了datax的jvm内存

python datax.py --jvm="-Xms3G -Xmx3G" ../job/oom.json

最后还是会报OOM。

只能去找究竟是那一部分代码产生了异常。

找到datax运行的进程编号 6630,把jvm的运行快照dump下来。

 jmap -dump:format=b,file=/tmp/6630_jmap_dump.hprof 6630

导入到MemoryAnalyzer里。

先看Histogram,列出内存中的对象,对象的个数以及大小。

Histogram

打开Dominator Tree,可以看到这个Ox752227ea8的线程,以及线程里的一个ArrayList对象占用了99.80%的空间,继续展开到com.gbase.jdbc.ByteArrayRow类。

Dominator Tree

再看一下Leak Suspects 

自动分析内存泄漏的原因,看到如下信息。

Leak Suspects 

点开调用栈追踪。

THread Stack

至此已经能定位到是在读取gbase数据的时候,一次性读取的数据量太大了,导致datax的内存泄漏报出了OOM,也就是我们配置的fetchSize参数没有生效。

最终问题发现是在url拼接的时候没有把useCursorFetch=true带上,和mysql类似,gbase在读取的时候要使fetchSize参数生效需要拼接useCursorFetch=true。


你可能感兴趣的:(DataX java.lang.OutOfMemoryError: GC overhead limit exceeded 一次OOM问题排查)