【问题标题】:java.lang.OutOfMemoryError with StringBuilderjava.lang.OutOfMemoryError 与 StringBuilder
【发布时间】:2012-10-25 11:53:08
【问题描述】:

我在 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 如何将它的大小加倍。但是在我的情况下,我总是在 child 中创建一个新的 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();

【问题讨论】:

  • 你的情况如何?在我看来,你的情况并没有停止。
  • 你能发布 OOME 的堆栈跟踪吗?
  • 您对StringBuilder 实例进行了哪些操作?
  • 你能详细说明conditionsomeConditionMet吗?
  • 当您使用 JDBC 资源时,您需要通过 close() 来正确清理它们。如果不这样做,将导致内存泄漏。您第一次意识到此泄漏可能是在您尝试构建字符串但没有足够的内存时。

标签: java memory-leaks stringbuilder heap-memory


【解决方案1】:

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

没有明白你的意思。您能解释一下您要指出的内容吗?

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

以下代码建议您创建一个语句,对其调用 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/

【讨论】:

  • 我自己不在代码中管理连接。我正在使用 Spring 和 Hibernate/JPA 来管理连接。还是有连接点没有正确关闭?
  • AFAIK,即使使用 Spring,您也需要关闭语句。
猜你喜欢
  • 1970-01-01
  • 2017-04-22
  • 2017-05-27
  • 2020-06-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
相关资源
最近更新 更多