-1

我在 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();
4

1 回答 1

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/

于 2012-11-05T16:18:06.143 回答