利用PreparedStatement对象进行批量操作(executeBatch),报内存溢出异常(OutOfMemoryError)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用PreparedStatement对象进行批量操作(executeBatch),报内存溢出异常(OutOfMemoryError)相关的知识,希望对你有一定的参考价值。

rs 是一个结果集对象,由一个查询语句得出。记录数100000余。

........
String baseSql = "insert into tableA(ColA,ColB,ColC) values(?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(baseSql);
int flag = 0;
while(rs.next())
pstmt.setString(1,rs.get(1));
pstmt.setString(2,rs.get(2));
pstmt.setString(3,rs.get(3));
pstmt.addBatch();

flag++;
if(flag % 10000 == 0)
pstmt.executeBatch();
System.out.println("====" + flag);


pstmt.executeBatch();
conn.commit();
.....

程序运行结果显示,当执行第8个批次操作的时候报错,内容如下:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.Vector.ensureCapacityHelper(Vector.java:226)
at java.util.Vector.addElement(Vector.java:573)
at oracle.jdbc.driver.OracleResultSetCacheImpl.put(OracleResultSetCacheImpl.java:67)
at oracle.jdbc.driver.ScrollableResultSet.putCachedValueAt(ScrollableResultSet.java:1951)
at oracle.jdbc.driver.ScrollableResultSet.cacheRowAt(ScrollableResultSet.java:1595)
at oracle.jdbc.driver.ScrollableResultSet.isValidRow(ScrollableResultSet.java:1571)
at oracle.jdbc.driver.ScrollableResultSet.next(ScrollableResultSet.java:301)

我想知道问题到底出在了哪里!!!明明是分批操作,而且前几批是成功了的啊!如果哪个对象惹得祸,它又是如何导致异常发生的?

解决办法:
1.加大内存,你一个内部循环搞定,产生了很多的句柄,堆栈内存放不下了
2.将一次操作封装到一个方法中,使用另一个方法来循环调用你封装的方法,自然就不会产生过多的无效句柄
参考技术A 我对这个问题也很感兴趣,能不能把完整的异常发给我,我试试能不能解决

参考资料:有问题,可以hi我

以上是关于利用PreparedStatement对象进行批量操作(executeBatch),报内存溢出异常(OutOfMemoryError)的主要内容,如果未能解决你的问题,请参考以下文章

statement与preparedStatement 批量操作(转)

Statement和PreparedStatement批量更新

JDBC批量插入性能简单分析

PreparedStatement 以及事务的注意事项

35 JDBC批量插入数据二

Java PrepareStatement