使用StringBuilder的java.lang.OutOfMemoryError

时间:2012-11-05 15:51:47

标签: java memory-leaks stringbuilder heap-memory

我在Java中使用StringBuilder类以如下方式在方法中创建一个大字符串值:

void parent() {

   int result = 0;

   while(true) {
     String s = "Some value";
     result = child(s);

     if(result == -1) {
        break;
     }
   }
}

int child(String s) {

   result = xDao.createNativeQuery(s).getResultList();

   if(result == null) {
       return -1;
   }

   StringBuilder builder = new StringBuilder()

   builder.append("INSERT INTO table_name VALUES(");

   for(int i = 0; i < result.length; i++) {
          builder.append(Message.Format("{0}, {0}..", result[i].val1, result[i].val2..); // This will create some big string.
   }

   // Do some operation with builder.
   dataDao.createNativeQuery(builder.toString()).executeUpdate();


   return 0;
}

现在说,child()运行了100多次,然后在第70次左右(或任何更高的数字)后,我得到了java.lang.OutOfMemoryError。

我已阅读了这篇文章http://mohammed-technical.blogspot.in/2010/09/javalangoutofmemoryerror-with.html

它解释了StringBuilder如何将其大小加倍。但就我而言,我总是在子内部创建一个新的StringBuilder实例,那么为什么因为StringBuilder而抛出java.lang.OutOfMemoryError呢?

有什么建议吗?

更新:

我实际上是使用StringBuilder创建SQL插入语句。因此会发生以下操作:

 builder.append("INSERT INTO table_name VALUES(");

 While(condition) {
          builder.append(Message.Format("{0}, {0}..", var1, var2..); // This will create some big string.
 }

然后最终在child()本身中调用以下行:

dataDao.createNativeQuery(builder.toString()).executeUpdate();

1 个答案:

答案 0 :(得分:0)

使用JDBC资源时,需要通过close()来正确清理它们。如果不这样做会导致内存泄漏。第一次你意识到这个泄漏可能是当你尝试构建字符串并且没有足够的内存时。

  

没有明白你的观点。你能解释一下你想要指出什么吗?

当您创建PreparedStatement或ResultSet时,您必须关闭()它们,否则它们将继续使用内存,因为它们的Connection包含对它们的引用。

以下代码建议您创建一个Statement,在其上调用executeUpdate()然后丢弃它。不幸的是,这不适用于JDBC。

dataDao.createNativeQuery(builder.toString()).executeUpdate();

http://www.java-blog.com/correct-closing-jdbc-resources

http://www.ibm.com/developerworks/websphere/library/bestpractices/closing_and_releasing_jdbc_resources.html

http://blog.shinetech.com/2007/08/04/how-to-close-jdbc-resources-properly-every-time/