【问题标题】:Possible memory leak due to not using StringBuffer?由于不使用 StringBuffer 可能导致内存泄漏?
【发布时间】:2009-07-22 13:28:53
【问题描述】:

以下代码会导致内存泄漏吗?使用 StringBuffer 真的会提高内存使用率吗?

一点背景知识:一位同事一直在推动他关于内存泄漏的理论,他认为这是有问题的代码(没有进行任何类型的分析),他声称这会导致内存泄漏。我不同意这一点,所以我想我会把它交给其他一些开发人员以获得第三方的意见。

 List partCollection = new ArrayList()

 String partKeyID = null;
 String sPartNbr = null;
 String partDescription = null; 

 while(rsPartRes.next())
 {
        partKeyID = rsPartRes.getString("PART_KEY_ID"); 
        sPartNbr = rsPartRes.getString("PART_NBR"); 
        partDescription = rsPartRes.getString("PART_DESC");

        SomeValueObject someValueObject = new SomeValueObject();
        someValueObject.setPartKeyID(partKeyID);
        someValueObject.setSPartNbr(sPartNbr);
        someValueObject.setPartDescription(partDescription);

        partCollection.add(someValueObject);
 }

假设 rsPartRes 是此代码中的一个 ResultSet,它可能包含 100 多条记录。基本上,他担心的是,因为我们正在循环遍历这个结果集而不使用 StringBuffer(在这种情况下,我什至不确定你将如何使用它),它可能会导致内存泄漏。是否有任何人在这里看到这可能导致内存泄漏或性能问题的情况......?

【问题讨论】:

  • 不,这是从 DB 代码块中提取的相当标准的 JDBC 对象。
  • 当然,假设之后有一个 rsPartRes.close() 和一个 psPartRes.close()(你使用的 PreparedStatement)。
  • 你能贴出 SomeValueObject 代码吗,那是唯一可以寻找内存泄漏的地方吗?
  • SomeValueObject 是一个假设的对象,但它纯粹是一个 Bean。

标签: java memory-management jdbc memory-leaks resultset


【解决方案1】:

据我所知,这里没有必要使用StringBuffer

使用StringBuffer 来提高性能的唯一原因是您一遍又一遍地连接Strings。

String result = "";
while (condition) {
    result += somethingElse;
}

或者(现在StringBuilderStringBuffer 的更好替代品)

StringBuilder result = new StringBuilder();
while (condition) {
    result.append(somethingElse);
}

第二段代码的性能要好得多。

【讨论】:

  • 我想在他们的代码库的其他地方有一些代码使用这个 List 并且 StringBuffer / StringBuilder 工作,可能是网页表。当然这应该在 JSP 中完成...
  • 我将此标记为已接受的答案。我认为我要寻找的答案是,除非没有进行连接或严重的字符串操作,否则就不需要 StringBuffer。
【解决方案2】:

不,这不会导致内存泄漏。但是,在循环内声明变量会更简洁:

 List partCollection = new ArrayList();

 while(rsPartRes.next())
 {
     String partKeyID = rsPartRes.getString("PART_KEY_ID"); 
     String sPartNbr = rsPartRes.getString("PART_NBR"); 
     String partDescription = rsPartRes.getString("PART_DESC");

     SomeValueObject someValueObject = new SomeValueObject();
     someValueObject.setPartKeyID(partKeyID);
     someValueObject.setSPartNbr(sPartNbr);
     someValueObject.setPartDescription(partDescription);

     partCollection.add(someValueObject);
 }

为什么你需要这些变量甚至都不明显:

 while(rsPartRes.next())
 {
     SomeValueObject someValueObject = new SomeValueObject();
     someValueObject.setPartKeyID(rsPartRes.getString("PART_KEY_ID"));
     someValueObject.setSPartNbr(rsPartRes.getString("PART_NBR"));
     someValueObject.setPartDescription(rsPartRes.getString("PART_DESC"));

     partCollection.add(someValueObject);
 }

(使用泛型也会更好,但那是另一回事......)

您的同事打算如何使用StringBuffer?这里没有进行字符串操作...

【讨论】:

  • 乔恩,同意你的编码建议。我不完全确定 StringBuffer 的建议是什么。但我认为我的观点与您所说的完全一样......“这里没有进行字符串操作......”
【解决方案3】:

他认为泄露了什么?

不确定 StringBuilder 在这里有何帮助,因为您似乎没有构建(连接)任何字符串。除非 SomeValueObject() 内部发生了什么事

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 2016-02-15
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    相关资源
    最近更新 更多