首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >内存不足错误: Java堆空间- PreparedStatement MySQL

内存不足错误: Java堆空间- PreparedStatement MySQL
EN

Stack Overflow用户
提问于 2015-09-11 04:38:07
回答 3查看 5.5K关注 0票数 2
代码语言:javascript
复制
void insert(ArrayList myList){
       conn = openDBConnection(); //Database Connection
       Iterator iterator = myList.iterator();
       while(iterator.hasNext()){
           insertIntoDB((myClass)iterator.next(),conn);
       }
       closeDBConnection();
   }

   void insertIntoDB(myClass myObject, Connection conn){
     String query = "insert into myTable values(?,?)";
     PreparedStatement myStatement = conn.prepareStatement(query);
     myStatement.setInt(1,myObject.getMyKey());
     myStatement.setInt(2,myObject.getMyValue());
     myStatement.execute();
    }

在上面的代码中,myList是一个条目超过1.2M的对象的arrayList。在插入大约1000条记录后,我收到以下错误:

代码语言:javascript
复制
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at com.mysql.jdbc.PreparedStatement.<init>(PreparedStatement.java:437)
    at com.mysql.jdbc.Connection.clientPrepareStatement(Connection.java:2187)
    at com.mysql.jdbc.Connection.prepareStatement(Connection.java:4829)
    at com.mysql.jdbc.Connection.prepareStatement(Connection.java:4734)
    at com.att.research.space.SpaceDaoImpl.insertMapping(SpaceDaoImpl.java:99)
    at com.att.research.space.ElementMappingLoader.insertMappingData(ElementMappingLoader.java:68)
    at com.att.research.space.CorrelationEngine.loadMappingFiles(CorrelationEngine.java:69)
    at com.att.research.space.CorrelationEngine.main(CorrelationEngine.java:25)

我尝试在迭代器循环中使用System.gc()。但我不认为这是一种好的编码方式,而且它也消耗了大量的CPU周期。

上面的代码是我的原始代码的示例代码格式。

EN

回答 3

Stack Overflow用户

发布于 2015-09-11 04:54:04

PreparedStatement的全部意义在于只创建一次并绑定变量。

我建议你这样写:

代码语言:javascript
复制
private static final String INSERT_QUERY = "insert into myTable values(?,?)";

public int insert(Connection c, List<MyClass> myList) {
    int numRows = 0;
    PreparedStatement ps = null;    
    try {
        ps = c.prepareStatement(INSERT_QUERY);
        for (MyClass x : myList) {
            ps.setInt(1, x.getMyKey());
            ps.setInt(2, x.getMyValue());
            numRows += ps.executeUpdate();          
        }
    } finally {
       close(ps);
    }
    return numRows;
}

我给你留下了一些细节(例如close方法)。

一句忠告:不要再喜欢把所有东西都命名为"MyFoo“。使用这样的命名约定,您的代码是不可读的。更仔细地考虑你如何命名事物。

票数 2
EN

Stack Overflow用户

发布于 2015-09-11 04:45:30

将语句移出循环,改为使用用户addBatch()和executeBatch

票数 1
EN

Stack Overflow用户

发布于 2018-08-08 07:38:36

避免finally块的内存泄漏应该首先解决;然而,如果它只是一个非常大的结果集,我发现这很有用:

http://benjchristensen.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/

即添加

代码语言:javascript
复制
stmt.setFetchSize(Integer.MIN_VALUE);

在运行stmt.executeQuery()之前;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32511190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档