报错样例
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
当服务器向客户端发送数据时