exception “GC Overhead limit exceeded错误:生成大于1.5G的数据,导入 数据量非常大,可能会导致一个错误

当使用Sqoop导入大量数据到Hive时,由于一次性加载所有行到内存,可能导致'GC Overhead limit exceeded'错误。解决方法包括指定mappers数量、调整JVM内存或设置数据库返回数据的批处理方式,如在JDBC连接字符串中添加参数以分批读取数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误:
exception “GC Overhead limit exceeded
原因:
Why Sqoop Import throws this exception?
The answer is – During the process, RDBMS database (NOT SQOOP) fetches all the rows at one shot and tries to load everything into memory. This causes memory spill out and throws error. To overcome this you need to tell RDBMS database to return the data in batches. The following parameters “?dontTrackOpenResources=true&defaultFetchSize=10000&useCursorFetch=true” following the jdbc connection string tells database to fetch 10000 rows per batch.

 

因为数据量较大,sqoop在导入hive的时候会将数据直接读到内存中,然后会导致内存溢出。

解决方案:

1、指定mappers的数量(默认为4个,数量最好不要超过节点的个数)

sqoop job --exec gp1813_user -- --num-mappers 8;

2、调整jvm的内存,直接加在sqoop的job中。

 -Dmapreduce.map.memory.mb=6000 \
 -Dmapreduce.map.java.opts=-Xmx1600m \
 -D
`Exception in thread "pool-1-thread-3" java.lang.OutOfMemoryError: GC overhead limit exceeded` 是 JVM 抛出的一种内存溢出错误,表示垃圾回收(GC)花费的时间过长,并且回收的内存非常少。这通常意味着应用程序在尝试释放内存方面效率低下,部分时间都被浪费在频繁的垃圾收集上。 --- ### 错误原因分析 1. **内存泄漏** 程序中可能存在某些对象无法被正常回收的情况,例如静态集合类(如 `ArrayList`, `HashMap`)持有量无用的对象引用,导致这些对象始终不能被 GC 回收。 2. **堆小不足** 应用程序所需的内存量超过了 JVM 堆的最限制。如果堆配置较小而应用负载较高,则容易触发该问题。 3. **高频率的小型分配** 如果系统不断创建短生命周期的对象填满新生代空间,同时老年代几乎没有足够的空闲区域存放晋升对象,那么会导致量的 Minor GC 和 Full GC 发生。 4. **数据结构设计不合理** 使用不当的数据结构可能会占用过多内存资源,比如递归深度过、缓存策略不佳等。 5. **JVM 参数设置不合适** 默认情况下,当 GC 占用总运行时间的比例达到约 98%,并且每次回收仅能获得不到 2% 的可用内存时,就会触发此错误。这种阈值可通过 `-XX:+UseGCLimitHeap` 调整或关闭。 --- ### 解决方案 1. **检查内存泄露点** - 利用工具如 VisualVM, JProfiler 分析 heap dump 文件查找哪些类占据了最量的堆空间。 2. **增加 JVM 内存容量** - 修改启动脚本增最小(-Xms)/最(-Xmx)堆尺寸参数值。例如:`-Xms512m -Xmx2g`. 3. **优化代码及算法性能** - 避免不必要的对象生成以及过度依赖全局变量存储临时结果; - 审查业务逻辑是否存在循环引用等问题影响 GC 正常工作。 4. **调整 GC 策略与选项** - 更换合适的垃圾搜集器适合实际场景需求(Parallel Scavenge / CMS / G1 GC); - 关闭默认限制以避免因比例超标造成中断服务体验:`-XX:-UseGCOverheadLimit`; --- 以下是简单的案例说明如何定位并修复这类问题: 假设某项目存在如下片段: ```java List<String> list = new ArrayList<>(); for (int i=0; i<Integer.MAX_VALUE; ++i){ String str = UUID.randomUUID().toString(); list.add(str); } System.out.println("Execution completed"); ``` 上述代码试图向列表无限添加字符串元素直至超出物理硬件所能提供的极限位置因而必定崩溃. 正确的做法应该是限定容器规模或是及时清理不用的内容项譬如采用轮替机制保留固定历史记录长度即可有效缓解压力. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值