Возможна утечка памяти из-за того, что не используется StringBuffer?

Может ли следующий код вызвать утечку памяти? Действительно ли использование 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 (который, в данном случае, я даже не уверен, КАК вы будете его использовать), это может вызвать утечку памяти. Есть ли ЛЮБОЙ случай, который кто-либо видит здесь, где это может вызвать утечку памяти или проблемы с производительностью...?


person JasonStoltz    schedule 22.07.2009    source источник
comment
Нет, это довольно стандартное извлечение объекта JDBC из блока кода БД.   -  person JeeBee    schedule 22.07.2009
comment
Предполагая, что после этого, конечно, есть rsPartRes.close() и psPartRes.close() (использованный вами PreparedStatement).   -  person JeeBee    schedule 22.07.2009
comment
Можете ли вы опубликовать код SomeValueObject, это единственное место, где можно искать утечку памяти?   -  person Lazarus    schedule 22.07.2009
comment
SomeValueObject — это гипотетический объект, но это будет чисто Bean.   -  person JasonStoltz    schedule 22.07.2009


Ответы (3)


Насколько я могу судить, здесь нет необходимости использовать StringBuffer.

Единственной причиной использования StringBuffer для повышения производительности будет многократное объединение String.

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

или (в наши дни StringBuilder лучше заменить StringBuffer)

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

Второй фрагмент кода работает намного лучше.

person jjnguy    schedule 22.07.2009
comment
Я предполагаю, что где-то еще в их кодовой базе есть некоторый код, который использует этот список и работает ли StringBuffer / StringBuilder, возможно, с таблицей веб-страницы. Конечно, это должно быть сделано в JSP... - person JeeBee; 22.07.2009
comment
Я отмечаю это как принятый ответ. Я думаю, что ответ, который я ищу, заключается в том, что если не происходит конкатенации или серьезных манипуляций со строками, тогда не будет необходимости в StringBuffer. - person JasonStoltz; 22.07.2009

Нет, это не приведет к утечке памяти. Однако было бы чище объявить переменные внутри цикла:

 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? Здесь нет никаких манипуляций со строками...

person Jon Skeet    schedule 22.07.2009
comment
Джон, согласился с вашими предложениями по кодированию. Я не совсем уверен, каково было предложение StringBuffer. Но я думаю, что моя точка зрения будет именно такой, как вы сказали... Здесь нет манипуляций со строками... - person JasonStoltz; 22.07.2009

Что, по его мнению, течет?

Не уверен, как здесь помогает StringBuilder, поскольку вы, похоже, не создаете (объединяете) какие-либо строки. Если что-то не происходит внутри SomeValueObject()

person n8wrl    schedule 22.07.2009