SAX, StringBuilder и утечка памяти - PullRequest
4 голосов
/ 06 января 2010

У меня странная проблема. Я анализирую документ с большим текстовым полем. В разделе персонажей я использую StringBuilder

currentStory.append(ch, start, length);

Затем в моем endElement я назначаю его соответствующему полю на моем объекте.

  if (name.equals(tagDesc)) {
     inDesc = false;
     if (currentItem != null ) {
         currentItem.setSummaryText(currentStory.toString());
     }
     currentStory.setLength(0);
  }

setSummaryText(String text) метод:

    public void setSummaryText(String text) {
      Story = text;
    }

И у меня заканчивается память.

Если я изменю setSummaryText на нечто совершенно странное, как это

public void setSummaryText(String text) {
      char[] local = text.toString()
      Story = new String(local);
   }

Я в порядке. Я просто не могу понять, где я держу эту ссылку? Story - член var этого объекта, инициализированный с ""; Примечание. Присваивание локальной строковой переменной вместо char [] также не выполняется.

1 Ответ

5 голосов
/ 07 января 2010

Я думаю, что это может быть связано с оптимизацией производительности метода StringBuffer toString().

Sun Javadoc говорит следующее:

Этот метод может быть закодирован так, чтобы создать новый объект String без выделения новой памяти для хранения копии последовательности символов. Вместо этого строка может разделять память, используемую строковым буфером. Любая последующая операция, которая изменяет содержимое или емкость строкового буфера, должна сделать копию внутреннего буфера в это время. Эта стратегия эффективна для уменьшения объема памяти, выделяемой операцией конкатенации строк, когда она реализуется с использованием строкового буфера.

Поскольку вы повторно используете StringBuffer с setLength(0), возможно, хранится ссылка на все строки, созданные с помощью toString().

Заменить:

currentStory.setLength(0);

с:

currentStory = new StringBuffer();

и посмотрим, разрешит ли это это. Я не думаю, что это будет больше затрат, так как в обоих случаях вам нужно будет создать новый массив char[], так как в первом случае массив используется String, созданным с toString().

Кроме того, вам следует рассмотреть возможность использования StringBuilder, так как они предпочтительнее StringBuffer.

...