暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

GBase 8a采用流模式处理JDBC大结果集,避免内存不足 OutOfmemoryError: GC overhead limit exceeded

生命之源 2022-03-18
664

报错样例

java.lang.OutOfMemoryError: GC overhead limit exceeded

内存不足,垃圾回收超过限制次数了。


解决方案

因为jdbc默认是将所有结果集都缓冲到本地,以便提供前进,后退的双向移动功能,但会占用大量内存。如果业务上只有前进(next),则可以采用每次只读取最小单位数据,处理完了再读取下一部分,来减少内存的消耗。

这个问题,对任何数据库都存在。

ResultSet.TYPE_FORWARD_ONLY, 表示只会前进,不会后退。
ResultSet.CONCUR_READ_ONLY 表示数据只读,不会更新。
setFetchSize 指定每次读取的最小值,一行一行的处理。注意,这里Integer.MIN_VALUE隐藏了含义,一般都是流模式的开关。如果改成其它数字,请做详尽的测试确保内存使用符合要求。

Statement stat = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stat.setFetchSize(Integer.MIN_VALUE);

提示

如果你读取一行,处理一行,而且处理一行数据时间过长,会导致服务器端发送数据超时,需要参考以下内容:


参数

gcluster_send_client_date_timeout=30

当服务器向客户端发送数据时,如超过这个参数,将认定超时。

一般发生在客户端阻塞,比如jvm垃圾回收,或者客户端拿到部分数据后要进行一些处理,再读取下一批数据时,会产生timeout。

该参数用于防止客户端意外阻塞,大致SQL无法及时终止,且无法kill的现象。

服务器端报错样例

gbase_forward_result failed to write for client

客户端报错样例:


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论